Fixpoint BDDmu_eval (f : mu_form) :
BDDconfig -> list ad -> Brel_env -> BDDconfig * ad :=
fun cfg ul bre =>
match f with
| mu_0 => (cfg, BDDzero)
| mu_1 => (cfg, BDDone)
| mu_ap p => BDDvar_make gc cfg ul p
| mu_rel_var P =>
match MapGet _ bre P with
| None => (cfg, BDDzero)
| Some node => (cfg, node)
end
| mu_neg g =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) => BDDneg gc cfgg (nodeg :: ul) nodeg
end
| mu_and g h =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) =>
match BDDmu_eval h cfgg (nodeg :: ul) bre with
| (cfgh, nodeh) =>
BDDand gc cfgh (nodeh :: nodeg :: ul) nodeg nodeh
end
end
| mu_or g h =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) =>
match BDDmu_eval h cfgg (nodeg :: ul) bre with
| (cfgh, nodeh) => BDDor gc cfgh (nodeh :: nodeg :: ul) nodeg nodeh
end
end
| mu_impl g h =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) =>
match BDDmu_eval h cfgg (nodeg :: ul) bre with
| (cfgh, nodeh) =>
BDDimpl gc cfgh (nodeh :: nodeg :: ul) nodeg nodeh
end
end
| mu_iff g h =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) =>
match BDDmu_eval h cfgg (nodeg :: ul) bre with
| (cfgh, nodeh) =>
BDDiff gc cfgh (nodeh :: nodeg :: ul) nodeg nodeh
end
end
| mu_all t g =>
match MapGet _ bte t with
| None => (cfg, BDDzero)
| Some nodet =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) => BDDmu_all N gc cfgg (nodeg :: ul) nodet nodeg
end
end
| mu_ex t g =>
match MapGet _ bte t with
| None => (cfg, BDDzero)
| Some nodet =>
match BDDmu_eval g cfg ul bre with
| (cfgg, nodeg) => BDDmu_ex N gc cfgg (nodeg :: ul) nodet nodeg
end
end
| mu_mu P g =>
fst
(BDDiter2n
(fun cfg node =>
BDDmu_eval g cfg (node :: ul) (MapPut _ bre P node)) cfg BDDzero
N)
end.

Lemma BDDmu_eval_ok :
forall (f : mu_form) (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 f bre ->
f_bte_ok f bte ->
BDDconfig_OK (fst (BDDmu_eval f cfg ul bre)) /\
config_node_OK (fst (BDDmu_eval f cfg ul bre))
(snd (BDDmu_eval f cfg ul bre)) /\
used_nodes_preserved cfg (fst (BDDmu_eval f cfg ul bre)) ul /\
bool_fun_eq
(bool_fun_of_BDD (fst (BDDmu_eval f cfg ul bre))
(snd (BDDmu_eval f cfg ul bre))) (bool_fun_of_bool_expr (mu_eval f re)).