Zulip Chat Archive
Stream: lean4
Topic: string unification
Colin S. Gordon (Aug 19 2022 at 16:59):
I have been bumping into a seeming confusion with (I presume, perhaps incorrectly) the special status of string literals in Lean. Consider:
class Good (s:String) where
blah : Unit
instance g1 : Good (String.mk ['1']) where
blah := ()
def onlyGood (s:String)[Good s] : String := s
-- next line Failed to synthesize instance Good "1"
theorem chk : onlyGood "1" = String.mk ['1'] := by rfl
-- but
theorem but : "1" = String.mk ['1'] := by rfl
In principle all strings are constructed by application of String.mk
. In practice, uses of String.mk
don't seem to unify with the corresponding literal. Admittedly this is probably not a common use case for Lean. But I have a few different use cases where I really want to be able to unify string literals with strings that are programmatically constructed in some way (either by typeclass instance search, or by manually constructing a string literal via String.mk
, List.cons
, and so on in a macro. Is there a trick to doing this? or alternatively, if I construct a string in a macro, is there a reasonable way to get the macro to emit a string that will in fact unify with a literal written by hand in the source code?
Mario Carneiro (Aug 20 2022 at 07:01):
Although "1" = String.mk ['1']
is defeq, this is not provable with only unfolding reducible definitions, which is what instance search does
Mario Carneiro (Aug 20 2022 at 07:02):
this isn't anything specific to string literals; if you have instance : Good 1
where def one := 1
then Good one
won't be found
Mario Carneiro (Aug 20 2022 at 07:04):
Colin S. Gordon said:
if I construct a string in a macro, is there a reasonable way to get the macro to emit a string that will in fact unify with a literal written by hand in the source code?
Yes, if you have a string s
in a macro then quote s
is a string literal you can put into the generated term
Mario Carneiro (Aug 20 2022 at 07:07):
import Lean
macro "my_quote" n:ident : term =>
let s := n.getId.toString
`($(Lean.quote s))
#check my_quote hi.mom
-- "hi.mom" : String
class Good (s : String)
instance : Good (my_quote hi.mom) := {}
def onlyGood (s : String) [Good s] : String := s
example : onlyGood "hi.mom" = "hi.mom" := rfl
Colin S. Gordon (Aug 26 2022 at 23:49):
thanks!
Last updated: Dec 20 2023 at 11:08 UTC