(* (f_P_even P f true) means that all free occurrences of the relational variable P in f are under an even number of negations. (f_P_even P f false) means that all free occurrences of the relational variable P in f are under an odd number of negations. *)
Inductive f_P_even (P : ad) : mu_form -> bool -> Prop :=
| mu_0_even : f_P_even P mu_0 true
| mu_0_odd : f_P_even P mu_0 false
| mu_1_even : f_P_even P mu_1 true
| mu_1_odd : f_P_even P mu_1 false
| mu_ap_even : forall p : ad, f_P_even P (mu_ap p) true
| mu_ap_odd : forall p : ad, f_P_even P (mu_ap p) false
| mu_rel_var_even :
forall Q : ad,
f_P_even P (mu_rel_var Q) true
(* one new clause added ... *)
| mu_rel_var_odd :
forall Q : ad, Neqb P Q = false -> f_P_even P (mu_rel_var Q) false
| mu_neg_odd :
forall f : mu_form, f_P_even P f true -> f_P_even P (mu_neg f) false
| mu_neg_even :
forall f : mu_form, f_P_even P f false -> f_P_even P (mu_neg f) true
| mu_and_even :
forall f g : mu_form,
f_P_even P f true -> f_P_even P g true -> f_P_even P (mu_and f g) true
| mu_and_odd :
forall f g : mu_form,
f_P_even P f false ->
f_P_even P g false -> f_P_even P (mu_and f g) false
| mu_or_even :
forall f g : mu_form,
f_P_even P f true -> f_P_even P g true -> f_P_even P (mu_or f g) true
| mu_or_odd :
forall f g : mu_form,
f_P_even P f false ->
f_P_even P g false -> f_P_even P (mu_or f g) false
| mu_impl_even :
forall f g : mu_form,
f_P_even P f false ->
f_P_even P g true -> f_P_even P (mu_impl f g) true
| mu_impl_odd :
forall f g : mu_form,
f_P_even P f true ->
f_P_even P g false -> f_P_even P (mu_impl f g) false
| mu_iff_even :
forall f g : mu_form,
f_P_even P f true ->
f_P_even P g true ->
f_P_even P f false ->
f_P_even P g false -> f_P_even P (mu_iff f g) true
| mu_iff_odd :
forall f g : mu_form,
f_P_even P f true ->
f_P_even P g true ->
f_P_even P f false ->
f_P_even P g false -> f_P_even P (mu_iff f g) false
| mu_all_even :
forall (t : ad) (f : mu_form),
f_P_even P f true -> f_P_even P (mu_all t f) true
| mu_all_odd :
forall (t : ad) (f : mu_form),
f_P_even P f false -> f_P_even P (mu_all t f) false
| mu_ex_even :
forall (t : ad) (f : mu_form),
f_P_even P f true -> f_P_even P (mu_ex t f) true
| mu_ex_odd :
forall (t : ad) (f : mu_form),
f_P_even P f false -> f_P_even P (mu_ex t f) false
| mu_mu_P_even : forall f : mu_form, f_P_even P (mu_mu P f) true
| mu_mu_P_odd : forall f : mu_form, f_P_even P (mu_mu P f) false
| mu_mu_Q_even :
forall (Q : ad) (f : mu_form),
Neqb P Q = false -> f_P_even P f true -> f_P_even P (mu_mu Q f) true
| mu_mu_Q_odd :
forall (Q : ad) (f : mu_form),
Neqb P Q = false -> f_P_even P f false -> f_P_even P (mu_mu Q f) false.
Inductive f_ok : mu_form -> Prop :=
| mu_0_f_ok : f_ok mu_0
| mu_1_f_ok : f_ok mu_1
| mu_ap_f_ok : forall p : ad, f_ok (mu_ap p)
| mu_rel_var_f_ok : forall P : ad, f_ok (mu_rel_var P)
| mu_neg_f_ok : forall f : mu_form, f_ok f -> f_ok (mu_neg f)
| mu_and_f_ok : forall f g : mu_form, f_ok f -> f_ok g -> f_ok (mu_and f g)
| mu_or_f_ok : forall f g : mu_form, f_ok f -> f_ok g -> f_ok (mu_or f g)
| mu_impl_f_ok :
forall f g : mu_form, f_ok f -> f_ok g -> f_ok (mu_impl f g)
| mu_iff_f_ok : forall f g : mu_form, f_ok f -> f_ok g -> f_ok (mu_iff f g)
| mu_all_f_ok : forall (t : ad) (f : mu_form), f_ok f -> f_ok (mu_all t f)
| mu_ex_f_ok : forall (t : ad) (f : mu_form), f_ok f -> f_ok (mu_ex t f)
| mu_mu_f_ok :
forall (P : ad) (f : mu_form),
f_ok f -> f_P_even P f true -> f_ok (mu_mu P f).
Definition cfg_ul_bre_ok (cfg : BDDconfig) (ul : list ad)
(bre : Brel_env) :=
forall P node : ad, MapGet _ bre P = Some node -> used_node' cfg ul node.
Definition cfg_ul_bte_ok (cfg : BDDconfig) (ul : list ad)
(bte : Btrans_env) :=
forall t node : ad, MapGet _ bte t = Some node -> used_node' cfg ul node.
Definition cfg_re_bre_ok (cfg : BDDconfig) (re : rel_env)
(bre : Brel_env) :=
forall P node : ad,
MapGet _ bre P = Some node ->
bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_bool_expr (re P)).
Definition cfg_te_bte_ok (cfg : BDDconfig) (te : trans_env)
(bte : Btrans_env) :=
forall t node : ad,
MapGet _ bte t = Some node ->
bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_bool_expr (te t)).
Definition f_bre_ok (f : mu_form) (bre : Brel_env) :=
forall P : ad, mu_rel_free P f = true -> in_dom _ P bre = true.
Definition f_bte_ok (f : mu_form) (bte : Btrans_env) :=
forall t : ad, mu_t_free t f = true -> in_dom _ t bte = true.

(* Specifications: *)
Lemma mu_and_bre_ok :
forall (g h : mu_form) (bre : Brel_env),
f_bre_ok (mu_and g h) bre -> f_bre_ok g bre /\ f_bre_ok h bre.
Lemma mu_or_bre_ok :
forall (g h : mu_form) (bre : Brel_env),
f_bre_ok (mu_or g h) bre -> f_bre_ok g bre /\ f_bre_ok h bre.
Lemma mu_impl_bre_ok :
forall (g h : mu_form) (bre : Brel_env),
f_bre_ok (mu_impl g h) bre -> f_bre_ok g bre /\ f_bre_ok h bre.
Lemma mu_iff_bre_ok :
forall (g h : mu_form) (bre : Brel_env),
f_bre_ok (mu_iff g h) bre -> f_bre_ok g bre /\ f_bre_ok h bre.
Lemma mu_and_bte_ok :
forall (g h : mu_form) (bte : Btrans_env),
f_bte_ok (mu_and g h) bte -> f_bte_ok g bte /\ f_bte_ok h bte.
Lemma mu_or_bte_ok :
forall (g h : mu_form) (bte : Btrans_env),
f_bte_ok (mu_or g h) bte -> f_bte_ok g bte /\ f_bte_ok h bte.
Lemma mu_impl_bte_ok :
forall (g h : mu_form) (bte : Btrans_env),
f_bte_ok (mu_impl g h) bte -> f_bte_ok g bte /\ f_bte_ok h bte.
Lemma mu_iff_bte_ok :
forall (g h : mu_form) (bte : Btrans_env),
f_bte_ok (mu_iff g h) bte -> f_bte_ok g bte /\ f_bte_ok h bte.
Lemma mu_all_bre_ok :
forall (t : ad) (g : mu_form) (bre : Brel_env),
f_bre_ok (mu_all t g) bre -> f_bre_ok g bre.
Lemma mu_all_bte_ok :
forall (t : ad) (g : mu_form) (bte : Btrans_env),
f_bte_ok (mu_all t g) bte -> f_bte_ok g bte.
Lemma mu_ex_bre_ok :
forall (t : ad) (g : mu_form) (bre : Brel_env),
f_bre_ok (mu_ex t g) bre -> f_bre_ok g bre.
Lemma mu_ex_bte_ok :
forall (t : ad) (g : mu_form) (bte : Btrans_env),
f_bte_ok (mu_ex t g) bte -> f_bte_ok g bte.
Lemma mu_mu_bre_ok :
forall (P node : ad) (g : mu_form) (bre : Brel_env),
f_bre_ok (mu_mu P g) bre -> f_bre_ok g (MapPut _ bre P node).
Lemma cfg_ul_re_bre_ok_preserved :
forall (cfg cfg1 : BDDconfig) (ul : list ad) (re : rel_env) (bre : Brel_env),
BDDconfig_OK cfg ->
BDDconfig_OK cfg1 ->
used_list_OK cfg ul ->
cfg_ul_bre_ok cfg ul bre ->
cfg_re_bre_ok cfg re bre ->
used_nodes_preserved cfg cfg1 ul ->
cfg_ul_bre_ok cfg1 ul bre /\ cfg_re_bre_ok cfg1 re bre.
Lemma cfg_ul_te_bte_ok_preserved :
forall (cfg cfg1 : BDDconfig) (ul : list ad) (te : trans_env)
(bte : Btrans_env),
BDDconfig_OK cfg ->
BDDconfig_OK cfg1 ->
used_list_OK cfg ul ->
cfg_ul_bte_ok cfg ul bte ->
cfg_te_bte_ok cfg te bte ->
used_nodes_preserved cfg cfg1 ul ->
cfg_ul_bte_ok cfg1 ul bte /\ cfg_te_bte_ok cfg1 te bte.
Lemma cfg_ul_bre_cons_ok :
forall (cfg : BDDconfig) (ul : list ad) (bre : Brel_env) (node : ad),
cfg_ul_bre_ok cfg ul bre -> cfg_ul_bre_ok cfg (node :: ul) bre.
Lemma cfg_ul_bte_cons_ok :
forall (cfg : BDDconfig) (ul : list ad) (bte : Btrans_env) (node : ad),
cfg_ul_bte_ok cfg ul bte -> cfg_ul_bte_ok cfg (node :: ul) bte.
Lemma cfg_re_bre_ok_put :
forall (cfg : BDDconfig) (re : rel_env) (bre : Brel_env)
(be : bool_expr) (P node : ad),
cfg_re_bre_ok cfg re bre ->
bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_bool_expr be) ->
cfg_re_bre_ok cfg (re_put re P be) (MapPut _ bre P node).
Lemma cfg_ul_bre_ok_put :
forall (cfg : BDDconfig) (ul : list ad) (bre : Brel_env) (P node : ad),
cfg_ul_bre_ok cfg ul bre ->
cfg_ul_bre_ok cfg (node :: ul) (MapPut _ bre P node).
Lemma BDDiter2n_lemma2 :
forall (te : trans_env) (bte : Btrans_env) (g : mu_form)
(Bf : mu_form -> BDDconfig -> list ad -> Brel_env -> BDDconfig * ad)
(f : mu_form -> rel_env -> bool_expr),
(forall (cfg : BDDconfig) (ul : list ad) (re : rel_env) (bre : Brel_env),
BDDconfig_OK cfg ->
used_list_OK cfg ul ->
cfg_ul_bre_ok cfg ul bre ->
cfg_re_bre_ok cfg re bre ->
cfg_ul_bte_ok cfg ul bte ->
cfg_te_bte_ok cfg te bte ->
f_bre_ok g bre ->
f_bte_ok g bte ->
BDDconfig_OK (fst (Bf g cfg ul bre)) /\
config_node_OK (fst (Bf g cfg ul bre)) (snd (Bf g cfg ul bre)) /\
used_nodes_preserved cfg (fst (Bf g cfg ul bre)) ul /\
bool_fun_eq
(bool_fun_of_BDD (fst (Bf g cfg ul bre)) (snd (Bf g cfg ul bre)))
(bool_fun_of_bool_expr (f g re))) ->
forall (n : nat) (P : ad) (cfg : BDDconfig) (node : ad)
(ul : list ad) (be : bool_expr) (re : rel_env) (bre : Brel_env),
BDDconfig_OK cfg ->
config_node_OK cfg node ->
used_list_OK cfg ul ->
cfg_ul_bre_ok cfg ul bre ->
cfg_re_bre_ok cfg re bre ->
cfg_ul_bte_ok cfg ul bte ->
cfg_te_bte_ok cfg te bte ->
(forall x : ad, f_bre_ok g (MapPut _ bre P x)) ->
f_bte_ok g bte ->
bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_bool_expr be) ->
BDDconfig_OK
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))) /\
config_node_OK
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
(snd
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))) /\
used_nodes_preserved cfg
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
ul /\
bool_fun_eq
(bool_fun_of_BDD
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
(snd
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))))
(bool_fun_of_bool_expr
(fst
(iter2n _ be_eq_dec (fun be : bool_expr => f g (re_put re P be)) be
n))) /\
snd
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n) =
snd (iter2n _ be_eq_dec (fun be : bool_expr => f g (re_put re P be)) be n).
Lemma BDDiter2n_lemma1 :
forall (te : trans_env) (bte : Btrans_env) (g : mu_form)
(Bf : mu_form -> BDDconfig -> list ad -> Brel_env -> BDDconfig * ad)
(f : mu_form -> rel_env -> bool_expr),
(forall (cfg : BDDconfig) (ul : list ad) (re : rel_env) (bre : Brel_env),
BDDconfig_OK cfg ->
used_list_OK cfg ul ->
cfg_ul_bre_ok cfg ul bre ->
cfg_re_bre_ok cfg re bre ->
cfg_ul_bte_ok cfg ul bte ->
cfg_te_bte_ok cfg te bte ->
f_bre_ok g bre ->
f_bte_ok g bte ->
BDDconfig_OK (fst (Bf g cfg ul bre)) /\
config_node_OK (fst (Bf g cfg ul bre)) (snd (Bf g cfg ul bre)) /\
used_nodes_preserved cfg (fst (Bf g cfg ul bre)) ul /\
bool_fun_eq
(bool_fun_of_BDD (fst (Bf g cfg ul bre)) (snd (Bf g cfg ul bre)))
(bool_fun_of_bool_expr (f g re))) ->
forall (n : nat) (P : ad) (cfg : BDDconfig) (node : ad)
(ul : list ad) (be : bool_expr) (re : rel_env) (bre : Brel_env),
BDDconfig_OK cfg ->
config_node_OK cfg node ->
used_list_OK cfg ul ->
cfg_ul_bre_ok cfg ul bre ->
cfg_re_bre_ok cfg re bre ->
cfg_ul_bte_ok cfg ul bte ->
cfg_te_bte_ok cfg te bte ->
(forall x : ad, f_bre_ok g (MapPut _ bre P x)) ->
f_bte_ok g bte ->
bool_fun_eq (bool_fun_of_BDD cfg node) (bool_fun_of_bool_expr be) ->
BDDconfig_OK
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))) /\
config_node_OK
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
(snd
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))) /\
used_nodes_preserved cfg
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
ul /\
bool_fun_eq
(bool_fun_of_BDD
(fst
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n)))
(snd
(fst
(BDDiter2n
(fun (cfg0 : BDDconfig) (node0 : ad) =>
Bf g cfg0 (node0 :: ul) (MapPut ad bre P node0)) cfg node n))))
(bool_fun_of_bool_expr
(fst
(iter2n _ be_eq_dec (fun be : bool_expr => f g (re_put re P be)) be
n))).