I'm messing around with coq and I'm trying to create a function that can be used to lookup something in a list and return an associated proof with it that the specified element is in the list.
In my case I have a list of tuples and I want to lookup based on the first element of the tuple.
So first I defined an assoc inductive predicate that proves an element is in the list. This has two cases. Either the element is in the head of the list or it is in the tail.
Inductive assoc (A : Set) (B : Set) : list (A * B) -> A -> B -> Prop :=
| assocHead : forall (l : list (A * B)) (a : A) (b : B), assoc A B (cons (a,b) l) a b
| assocTail : forall (l : list (A * B)) (a x : A) (b y : B), assoc A B l a b -> assoc A B ((x,y) :: l) a b.
Then I define a lookup function that given a list of tuples, a first element and an equality predicate returns either None or Some with the looked up element and a proof that the element is in the list.
Program Fixpoint lookup
(A : Set)
(B : Set)
(dec : (forall x y : A, {x = y} + {x <> y}))
(l : list (A * B))
(a : A)
{struct l}
: option {b : B | assoc A B l a b}
:= match l with
| [] => None
| (pair v t) :: tl => if dec v a
then (Some (exist (assoc A B ((pair v t) :: tl) a) t (assocHead A B tl a t)))
else match (lookup A B dec tl a) with
-- In the case below we have proven it's in the
-- tail of the list.
-- How to use that to create new proof with assocTail?
| Some (exist _ _ _) => None
| None => None
end
end.
The way it's written above compiles fine. But I can't figure out how to use the proof that is in the tl of the list to create a new proof that it's in the total list. I have tried various things like pattern matching in the third argument of exist but I can never get it to work.
Any help is appreciated!