Inductive pre_ad : Set :=
| pre_ad_empty : pre_ad
| pre_ad_O : pre_ad -> pre_ad
| pre_ad_I : pre_ad -> pre_ad.
Fixpoint pre_ad_concat (pa : pre_ad) : ad -> ad :=
fun a : ad =>
match pa with
| pre_ad_empty => a
| pre_ad_O pa' => pre_ad_concat pa' (Ndouble a)
| pre_ad_I pa' => pre_ad_concat pa' (Ndouble_plus_one a)
end.
Fixpoint st_compat_check_0 (pa : pre_ad) (sigma : signature)
(s : state) {struct s} : bool :=
match s with
| M0 => true
| M1 a p =>
match pl_compat_check p, MapGet nat sigma (pre_ad_concat pa a) with
| None, _ => false
| _, None => false
| Some n, Some m => beq_nat n m
end
| M2 x y =>
st_compat_check_0 (pre_ad_O pa) sigma x &&
st_compat_check_0 (pre_ad_I pa) sigma y
end.
Definition st_compat_check (s : state) (sigma : signature) : bool :=
st_compat_check_0 pre_ad_empty sigma s.
Fixpoint predta_compat_check (d : preDTA) : signature -> bool :=
fun sigma : signature =>
match d with
| M0 => true
| M1 a s => st_compat_check s sigma
| M2 x y => predta_compat_check x sigma && predta_compat_check y sigma
end.
Definition dta_compat_check (d : DTA) (sigma : signature) : bool :=
match d with
| dta p a => predta_compat_check p sigma
end.
Definition state_correct_wrt_sign_with_offset (s : state)
(sigma : signature) (pa : pre_ad) : Prop :=
forall (a : ad) (p : prec_list),
MapGet prec_list s a = Some p ->
exists n : nat,
MapGet nat sigma (pre_ad_concat pa a) = Some n /\ pl_tl_length p n.

(* Specifications: *)
Lemma state_correct_wrt_sign_with_offset_M2 :
forall (s0 s1 : state) (sigma : signature) (pa : pre_ad),
state_correct_wrt_sign_with_offset (M2 prec_list s0 s1) sigma pa ->
state_correct_wrt_sign_with_offset s0 sigma (pre_ad_O pa) /\
state_correct_wrt_sign_with_offset s1 sigma (pre_ad_I pa).
Lemma predta_correct_wrt_sign_M2 :
forall (d0 d1 : preDTA) (sigma : signature),
predta_correct_wrt_sign (M2 state d0 d1) sigma ->
predta_correct_wrt_sign d0 sigma /\ predta_correct_wrt_sign d1 sigma.
Lemma st_compat_check_0_correct :
forall (s : state) (sigma : signature) (pa : pre_ad),
state_correct_wrt_sign_with_offset s sigma pa ->
st_compat_check_0 pa sigma s = true.
Lemma st_compat_check_0_complete :
forall (s : state) (sigma : signature) (pa : pre_ad),
st_compat_check_0 pa sigma s = true ->
state_correct_wrt_sign_with_offset s sigma pa.
Lemma st_compat_check_correct :
forall (s : state) (sigma : signature),
state_correct_wrt_sign s sigma -> st_compat_check s sigma = true.
Lemma st_compat_check_complete :
forall (s : state) (sigma : signature),
st_compat_check s sigma = true -> state_correct_wrt_sign s sigma.
Lemma predta_compat_check_correct :
forall (d : preDTA) (sigma : signature),
predta_correct_wrt_sign d sigma -> predta_compat_check d sigma = true.
Lemma predta_compat_check_complete :
forall (d : preDTA) (sigma : signature),
predta_compat_check d sigma = true -> predta_correct_wrt_sign d sigma.
Lemma dta_compat_check_correct :
forall (d : DTA) (sigma : signature),
dta_correct_wrt_sign d sigma -> dta_compat_check d sigma = true.
Lemma dta_compat_check_complete :
forall (d : DTA) (sigma : signature),
dta_compat_check d sigma = true -> dta_correct_wrt_sign d sigma.