Definition node_OK (bs : BDDstate) (node : ad) :=
node = BDDzero \/ node = BDDone \/ in_dom _ node bs = true.

(* Specifications: *)
Lemma BDDbounded_node_OK :
forall (bs : BDDstate) (node : ad) (n : BDDvar),
BDDbounded bs node n -> node_OK bs node.
Lemma BDDalloc_allocates :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
MapGet _ (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)) =
Some (x, (l, r)).
Lemma BDDalloc_preserves_nodes :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
forall (a l1 r1 : ad) (x1 : BDDvar),
MapGet _ (fst cfg) a = Some (x1, (l1, r1)) ->
MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)).
Lemma BDDalloc_no_new_node :
forall (cfg : BDDconfig) (l l1 r r1 a : ad) (x x1 : BDDvar),
MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)) ->
a = snd (snd cfg) \/ MapGet _ (fst cfg) a = Some (x1, (l1, r1)).
Lemma BDDalloc_no_new_node_1 :
forall (cfg : BDDconfig) (l l1 r r1 a : ad) (x x1 : BDDvar),
MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x1, (l1, r1)) ->
(x1, (l1, r1)) = (x, (l, r)) \/
MapGet _ (fst cfg) a = Some (x1, (l1, r1)).
Lemma BDDalloc_preserves_zero :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
MapGet _ (fst (fst (BDDalloc cfg x l r))) BDDzero = None.
Lemma BDDalloc_preserves_one :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
MapGet _ (fst (fst (BDDalloc cfg x l r))) BDDone = None.
Lemma BDDalloc_keeps_state_OK :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
node_OK (fst cfg) l ->
node_OK (fst cfg) r ->
Neqb l r <> true ->
(forall (xl : BDDvar) (ll rl : ad),
MapGet _ (fst cfg) l = Some (xl, (ll, rl)) ->
BDDcompare xl x = Datatypes.Lt) ->
(forall (xr : BDDvar) (lr rr : ad),
MapGet _ (fst cfg) r = Some (xr, (lr, rr)) ->
BDDcompare xr x = Datatypes.Lt) ->
BDDstate_OK (fst (fst (BDDalloc cfg x l r))).
Lemma BDDalloc_adjusts_counter :
forall (cfg : BDDconfig) (x : BDDvar) (l r a : ad),
BDDconfig_OK cfg ->
(forall a : ad,
Nleb (snd (snd (fst (BDDalloc cfg x l r)))) a = true ->
MapGet _ (fst (fst (BDDalloc cfg x l r))) a = None) /\
Nleb (ad_S (ad_S N0)) (snd (snd (fst (BDDalloc cfg x l r)))) = true.
Lemma BDDalloc_keeps_sharing_OK :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
node_OK (fst cfg) l ->
node_OK (fst cfg) r ->
(forall (x' : BDDvar) (l' r' a : ad),
MapGet _ (fst cfg) a = Some (x', (l', r')) ->
(x, (l, r)) <> (x', (l', r'))) ->
BDDsharing_OK (fst (fst (BDDalloc cfg x l r)))
(fst (snd (fst (BDDalloc cfg x l r)))).
Lemma BDDalloc_semantics :
forall (cfg : BDDconfig) (l r : ad) (x : BDDvar),
BDDconfig_OK cfg ->
node_OK (fst cfg) l ->
node_OK (fst cfg) r ->
Neqb l r <> true ->
(forall (xl : BDDvar) (ll rl : ad),
MapGet _ (fst cfg) l = Some (xl, (ll, rl)) ->
BDDcompare xl x = Datatypes.Lt) ->
(forall (xr : BDDvar) (lr rr : ad),
MapGet _ (fst cfg) r = Some (xr, (lr, rr)) ->
BDDcompare xr x = Datatypes.Lt) ->
(forall (x' : BDDvar) (l' r' a : ad),
MapGet _ (fst cfg) a = Some (x', (l', r')) ->
(x, (l, r)) <> (x', (l', r'))) ->
BDDconfig_OK (fst (BDDalloc cfg x l r)) /\
MapGet _ (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)) =
Some (x, (l, r)) /\
(forall (a l' r' : ad) (x' : BDDvar),
(MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x', (l', r')) ->
MapGet _ (fst cfg) a = Some (x', (l', r')) \/
snd (BDDalloc cfg x l r) = a) /\
(MapGet _ (fst cfg) a = Some (x', (l', r')) ->
MapGet _ (fst (fst (BDDalloc cfg x l r))) a = Some (x', (l', r')))) /\
node_OK (fst (fst (BDDalloc cfg x l r))) (snd (BDDalloc cfg x l r)).