Module Import Prog := Syn.MkProg (EMProg).
Definition rank : function -> nat := ltac:(autorank function_beq ranklist).
(* QI *)
Definition cs (c : constructor) := 1%nat. (* same for all *)
(* Specifications *)
(* Conversion functions from/to term values/Coq types. *)
Fixpoint Pos_of_value (v : value) : positive := match v with
| Syntax.c_capply XHC [] => xH
| Syntax.c_capply XOC [v] => xO (Pos_of_value v)
| Syntax.c_capply XIC [v] => xI (Pos_of_value v)
| _ => xH
end.
Fixpoint N_of_value (v : value) : N := match v with
| Syntax.c_capply N0C [] => 0
| Syntax.c_capply NPosC [v] => N.pos (Pos_of_value v)
| _ => 0
end.
Fixpoint value_of_pos (n : positive) : value := match n with
| xH => c_capply XHC []
| xO a => c_capply XOC [value_of_pos a]
| xI a => c_capply XIC [value_of_pos a]
end.
Fixpoint pos_of_value p := match p with
| Syntax.c_capply XHC [] => xH
| Syntax.c_capply XOC [a] => xO (pos_of_value a)
| Syntax.c_capply XIC [a] => xI (pos_of_value a)
| _ => xH
end.
Definition value_of_N (n : N) : Syntax.value EMSyntax.constructor (* value *) :=
match n with
| 0%N => c_capply N0C []
| Npos a => c_capply NposC [value_of_pos a]
end.
Definition value_of_mask (m : Pos.mask) := match m with
| IsPos a => c_capply IsPosC [value_of_pos a]
| IsNeg => c_capply IsNegC []
| IsNul => c_capply IsNulC []
end.
Definition mask_of_value m := match m with
| Syntax.c_capply IsPosC [a] => IsPos (pos_of_value a)
| Syntax.c_capply IsNegC [] => IsNeg
| Syntax.c_capply IsNulC [] => IsNul
| _ => IsNul
end.
Definition value_of_comp c := match c with
| Eq => c_capply EqC []
| Lt => c_capply LtC []
| Gt => c_capply GtC []
end.
Definition comp_of_value v := match v with
| Syntax.c_capply EqC [] => Eq
| Syntax.c_capply LtC [] => Lt
| Syntax.c_capply GtC [] => Gt
| _ => Eq
end.
Definition value_of_bool b := match b with
| true => c_capply TrueC []
| false => c_capply FalseC []
end.
Definition bool_of_value v := match v with
| Syntax.c_capply TrueC [] => true
| Syntax.c_capply FalseC [] => false
| _ => false
end.
Definition pairN : Type := (N * N).
Definition value_of_pair (x : pairN) := c_capply PairC [value_of_N (fst x); value_of_N (snd x)].
Coercion value_of_N : N >-> Syntax.value.
Coercion value_of_pair : pairN >-> value.
Open Scope N_scope.

Lemma pred_double_correct p : forall t,
evaluates t (value_of_pos p) ->
evaluates (pred_doubleF (: t :)) (value_of_pos (Pos.pred_double p)).