Section LookupAssociativeList.
Variable (sigX sigY : finType).
Variable (X : eqType) (Y : Type) (cX : codable sigX X) (cY : codable sigY Y).
Notation sig := (sigList (sigPair sigX sigY)).
Hypothesis (cX_injective : injective cX).
Fixpoint lookup (x : X) (xs : list (X * Y)) {struct xs} : option Y :=
match xs with
| nil => None
| (x', y) :: xs' => if Dec (x = x') then Some y else lookup x xs'
end.
Local Definition retr_sig_sigX : Retract sigX sig := _.
Local Definition retr_sig_sigY : Retract sigY sig := _.
Definition Lookup_Step : pTM sig^+ (option bool) 4 :=
If (CaseList (FinType(EqType(sigPair sigX sigY))) @ [|Fin0; Fin2|] )
(CasePair _ _  ⇑ _ @ [|Fin2; Fin3|];;
If (CompareValues _ ⇑ retr_sig_sigX  @ [|Fin1; Fin3|])
(Return (MoveValue _ @ [|Fin2; Fin1|];; Reset _ @ [|Fin3|];; Reset _ @ [|Fin0|]) (Some true))
(Return (Reset _ @ [|Fin3|];; Reset _ @ [|Fin2|]) None))
(Return (ResetEmpty1 _ @ [|Fin0|]) (Some false)).
Definition Lookup_Step_size {sigX sigY : Type} {X : eqType} {Y : Type} {cX : codable sigX X} {cY : codable sigY Y} (xs : list (X*Y)) (x:X) : Vector.t (nat->nat) 4 :=
match xs with
| (x', y) :: xs' =>
if Dec (x=x')
then [| (*0*) CaseList_size0 (x', y) >> Reset_size xs';
Definition Lookup_T : tRel sig^+ 5 :=
fun tin k =>
exists (xs : list (X*Y)) (x : X),
tin[@Fin0] ≃ xs /\
tin[@Fin1] ≃ x /\
isVoid tin[@Fin2] /\ isVoid tin[@Fin3] /\ isVoid tin[@Fin4] /\
Lookup_steps x xs <= k.

(* legacy Lemma *)
Lemma Lookup_Terminates : projT1 Lookup ↓ Lookup_T.