I have a snippet of agda code of the following form:
Terminates : πΆ β S β Set
Terminates c s = Ξ£[ n β β ] ( Is-just (projβ (smallStepEvalwithFuel n ( c , just s ))))
evalAssiProg : β {i e} β S β (p : i := e) β Maybe S
evalAssiProg s (id κ= exp) with evalExp exp s
... | nothing = nothing -- Comp failed. i.e. Γ· by 0 error
... | just v = just (updateState id v s) -- Comp success
example : β i v exp s β ( a : i := exp ) β evalExp exp s β‘ just v β Terminates ( ππ π πκ a ) s
example i v e s (.i κ= .e) p with evalExp e s
... | just x = 1 , {!!} --<----------------------! Problem here
I'm hoping that the details don't matter too much, basically evalExp e s
has the form evalExp : Exp β S β Maybe Val
i.e. it takes an expression, a state, and spits out the value unless a divide by zero error occurs for example. So it is a tedious but simple function.
All I'm interested in is: how can I pattern match on evalExp e s
in example
, and have agda correctly work out that the only possible case is just x
but still if I look in the goal on the right hand side of the product I have that the goal is still waiting on the result of evalExp e s
:
Goal: Any (Ξ» _ β β€)
(Mini-C.Evaluation.evalAssiProg dRep sRep s (i Mini-C.Lang._:=_.κ= e)
| evalExp e s)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
i : Id
s : S
e : Exp
sRep : S-Representation dRep
p : just x β‘ just v
v : Val
x : Val
dRep : D-Representation
I believe the below snippet models your problem accurately:
module _ where
open import Data.Maybe
open import Data.Product
open import Relation.Binary.PropositionalEquality
open import Data.Unit
open import Data.Maybe.Relation.Unary.Any
variable
A B : Set
Terminates : β {A B : Set} β (A β Maybe B) β Set
Terminates f = Ξ£ _ Ξ» x β Is-just (f x)
example : β (f : A β Maybe B) x y β f x β‘ just y β Terminates f
example f x y p = x , {!!}
Here, the type of the hole is Is-just (f x)
, and we would like to use the proof p
to solve it. The problem is that we can't just write just tt
into the hole:
just _x_26 != f x of type Maybe B
when checking that the inferred type of an application
Any (Ξ» _ β β€) (just _x_26)
matches the expected type
Is-just (f x)
Because f x
doesn't reduce to just _
, since we know nothing about f
or x
. But wait, we do know something about it -- in p
. So we need to arrange for p
to make a difference here:
example : β (f : A β Maybe B) x y β f x β‘ just y β Terminates f
example f x y p = x , subst Is-just (sym p) (just tt)
Here, (after unification) we have just tt : Is-just (just y)
, and we rewrite its type with the equality sym p : just y β‘ f x
, to subst _ _ (just tt) : Is-just (f x)
which is exactly our goal.