(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Section Bool_fun.
Definition var_env := BDDvar -> bool.
Definition bool_fun := var_env -> bool.
Definition bool_fun_eq (bf1 bf2 : bool_fun) :=
forall vb : var_env, bf1 vb = bf2 vb.
Definition bool_fun_zero (vb : var_env) := false.
Definition bool_fun_one (vb : var_env) := true.
Definition bool_fun_neg (bf : bool_fun) : bool_fun :=
fun vb : var_env => negb (bf vb).
Definition bool_fun_or (bf1 bf2 : bool_fun) : bool_fun :=
fun vb : var_env => bf1 vb || bf2 vb.
Definition bool_fun_and (bf1 bf2 : bool_fun) : bool_fun :=
fun vb : var_env => bf1 vb && bf2 vb.
Definition bool_fun_impl (bf1 bf2 : bool_fun) : bool_fun :=
fun vb : var_env => implb (bf1 vb) (bf2 vb).
Definition bool_fun_iff (bf1 bf2 : bool_fun) : bool_fun :=
fun vb : var_env => eqb (bf1 vb) (bf2 vb).
Definition bool_fun_if (x : BDDvar) (bf1 bf2 : bool_fun) : bool_fun :=
fun vb : var_env => ifb (vb x) (bf1 vb) (bf2 vb).
Definition bool_fun_var (x : BDDvar) : bool_fun := fun vb : var_env => vb x.
Definition augment (vb : var_env) (x : BDDvar) (b : bool) : var_env :=
fun y : BDDvar => if Neqb x y then b else vb y.
Definition bool_fun_restrict (bf : bool_fun) (x : BDDvar)
(b : bool) : bool_fun := fun vb : var_env => bf (augment vb x b).
Definition bool_fun_independent (bf : bool_fun) (x : BDDvar) :=
forall b : bool, bool_fun_eq (bool_fun_restrict bf x b) bf.
Definition bool_fun_forall (x : BDDvar) (bf : bool_fun) :=
bool_fun_and (bool_fun_restrict bf x true) (bool_fun_restrict bf x false).
Definition bool_fun_ex (x : BDDvar) (bf : bool_fun) :=
bool_fun_or (bool_fun_restrict bf x true) (bool_fun_restrict bf x false).
Definition bool_fun_ext (bf : bool_fun) :=
forall vb vb' : var_env,
(forall x : BDDvar, vb x = vb' x) -> bf vb = bf vb'.
Inductive bool_expr : Set :=
| Zero : bool_expr
| One : bool_expr
| Var : BDDvar -> bool_expr
| Neg : bool_expr -> bool_expr
| Or : bool_expr -> bool_expr -> bool_expr
| ANd : bool_expr -> bool_expr -> bool_expr
| Impl : bool_expr -> bool_expr -> bool_expr
| Iff : bool_expr -> bool_expr -> bool_expr.
Fixpoint bool_fun_of_bool_expr (be : bool_expr) : bool_fun :=
match be with
| Zero => bool_fun_zero
| One => bool_fun_one
| Var x => bool_fun_var x
| Neg be' => bool_fun_neg (bool_fun_of_bool_expr be')
| Or be1 be2 =>
bool_fun_or (bool_fun_of_bool_expr be1) (bool_fun_of_bool_expr be2)
| ANd be1 be2 =>
bool_fun_and (bool_fun_of_bool_expr be1) (bool_fun_of_bool_expr be2)
| Impl be1 be2 =>
bool_fun_impl (bool_fun_of_bool_expr be1) (bool_fun_of_bool_expr be2)
| Iff be1 be2 =>
bool_fun_iff (bool_fun_of_bool_expr be1) (bool_fun_of_bool_expr be2)
end.

Lemma bool_fun_impl_preserves_eq :
forall bf1 bf1' bf2 bf2' : bool_fun,
bool_fun_eq bf1 bf1' ->
bool_fun_eq bf2 bf2' ->
bool_fun_eq (bool_fun_impl bf1 bf2) (bool_fun_impl bf1' bf2').