@@ -37,8 +37,10 @@ open import Data.Nat.Base as ℕ using (ℕ; zero; suc; _≡ᵇ_; _+_)
37
37
open import Data.Unit.Base using (⊤)
38
38
open import Data.Word.Base as Word using (toℕ)
39
39
open import Data.Product.Base using (_×_; map₁; _,_)
40
+ open import Function using (flip; case_of_)
40
41
41
42
open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong)
43
+ open import Relation.Nullary.Decidable.Core using (yes; no)
42
44
43
45
-- 'Data.String.Properties' defines this via 'Dec', so let's use the
44
46
-- builtin for maximum speed.
@@ -54,8 +56,10 @@ open import Reflection.AST.Literal as Literal
54
56
open import Reflection.AST.Meta as Meta
55
57
open import Reflection.AST.Name as Name
56
58
open import Reflection.AST.Term as Term
59
+ import Reflection.AST.Traversal as Traversal
57
60
58
61
open import Reflection.TCM.Syntax
62
+ open import Reflection.TCM.Utilities
59
63
60
64
-- Marker to keep anti-unification from descending into the wrapped
61
65
-- subterm.
@@ -102,6 +106,16 @@ private
102
106
notEqualityError : ∀ {A : Set } Term → TC A
103
107
notEqualityError goal = typeError (strErr "Cannot rewrite a goal that is not equality: " ∷ termErr goal ∷ [])
104
108
109
+ unificationError : ∀ {A : Set } → TC Term → TC Term → TC A
110
+ unificationError term symTerm = do
111
+ term' ← term
112
+ symTerm' ← symTerm
113
+ -- Don't show the same term twice.
114
+ let symErr = case term' Term.≟ symTerm' of λ where
115
+ (yes _) → []
116
+ (no _) → strErr "\n" ∷ termErr symTerm' ∷ []
117
+ typeError (strErr "cong! failed, tried:\n" ∷ termErr term' ∷ symErr)
118
+
105
119
record EqualityGoal : Set where
106
120
constructor equals
107
121
field
@@ -236,12 +250,17 @@ macro
236
250
withNormalisation false $ do
237
251
goal ← inferType hole
238
252
eqGoal ← destructEqualityGoal goal
239
- let uni = λ lhs rhs → do
240
- let cong-lam = antiUnify 0 lhs rhs
241
- cong-tm ← `cong eqGoal cong-lam x≡y
242
- unify cong-tm hole
253
+ let makeTerm = λ lhs rhs → `cong eqGoal (antiUnify 0 lhs rhs) x≡y
243
254
let lhs = EqualityGoal.lhs eqGoal
244
255
let rhs = EqualityGoal.rhs eqGoal
245
- -- When using ⌞_⌟ with ≡⟨ ... ⟨, (uni lhs rhs) fails and
246
- -- (uni rhs lhs) succeeds.
247
- catchTC (uni lhs rhs) (uni rhs lhs)
256
+ let term = makeTerm lhs rhs
257
+ let symTerm = makeTerm rhs lhs
258
+ let uni = _>>= flip unify hole
259
+ -- When using ⌞_⌟ with ≡⟨ ... ⟨, (uni term) fails and
260
+ -- (uni symTerm) succeeds.
261
+ catchTC (uni term) $
262
+ catchTC (uni symTerm) $ do
263
+ -- If we failed because of unresolved metas, restart.
264
+ blockOnMetas goal
265
+ -- If we failed for a different reason, show an error.
266
+ unificationError term symTerm
0 commit comments