我对 Agda 很熟悉。我决定尝试一下 Lean,但我发现命题相等性真的让我很困扰。有时候我发现 rfl 能正常工作,但有时候却不行,原因我完全不明白,这真让人沮丧。举个例子:
inductive Λ where
| var : String → Λ
| app : Λ → Λ → Λ
| abs : String → Λ → Λ
deriving Repr, BEq, DecidableEq
def FV : Λ → HashSet String
| Λ.var x => HashSet.ofList [x]
| Λ.app m n => FV m ∪ FV n
| Λ.abs x m => (FV m).erase x
#eval FV (Λ.var "x") -- Std.HashSet.ofList ["x"]
example : FV (Λ.var "x") = HashSet.ofList ["x"] := rfl -- fine
example : (2 == 1 + 1) = true := rfl -- fine
#eval FV (Λ.var "x") == HashSet.ofList ["x"] -- true
example : (FV (Λ.var "x") == HashSet.ofList ["x"]) = true := rfl
--type mismatch
-- rfl
--has type
-- ?m.9390 = ?m.9390 : Prop
--but is expected to have type
-- (FV (Λ.var "x") == HashSet.ofList ["x"]) = true : Prop
表达式的计算结果与预期一致,但在前两个例子中, rfl 运行良好,但在最后一个例子中却莫名其妙地不行,似乎没有减少 = 两边的项。我可以想象两个具有相同值的 HashSet 并不总是相等,因为它们可能最终位于不同的 bucket 中,但我不确定这是否是问题所在,因为它的计算结果似乎很好。