Library Stalmarck.normalize


Require Export BoolAux.
Require Export rZ.

Inductive boolOp : Set :=
  | ANd : boolOp
  | Or : boolOp
  | Impl : boolOp
  | Eq : boolOp.

Inductive Expr : Set :=
  | V : rNatExpr
  | N : ExprExpr
  | Node : boolOpExprExprExpr.


Definition boolOpFun (n : boolOp) :=
  match n with
  | ANdandb
  | Ororb
  | Implimplb
  | normalize.Eqeqb
  end.

Fixpoint Eval (f : rNatbool) (e : Expr) {struct e} : bool :=
  match e with
  | V nf n
  | normalize.N pnegb (Eval f p)
  | Node n p qboolOpFun n (Eval f p) (Eval f q)
  end.

Inductive rBoolOp : Set :=
  | rAnd : rBoolOp
  | rEq : rBoolOp.

Definition rBoolOpFun (n : rBoolOp) :=
  match n with
  | rAndandb
  | rEqeqb
  end.

Inductive rExpr : Set :=
  | rV : rNatrExpr
  | rN : rExprrExpr
  | rNode : rBoolOprExprrExprrExpr.

Fixpoint rEval (f : rNatbool) (x : rExpr) {struct x} : bool :=
  match x with
  | rV nf n
  | rN xnegb (rEval f x)
  | rNode n x1 x2rBoolOpFun n (rEval f x1) (rEval f x2)
  end.

Fixpoint maxVar (e : rExpr) : rNat :=
  match e with
  | rV nn
  | rN pmaxVar p
  | rNode n p qrmax (maxVar p) (maxVar q)
  end.

Inductive inRExpr (n : rNat) : rExprProp :=
  | inRV : inRExpr n (rV n)
  | inRN : e : rExpr, inRExpr n einRExpr n (rN e)
  | inRNodeLeft :
       (i : rBoolOp) (e1 e2 : rExpr),
      inRExpr n e1inRExpr n (rNode i e1 e2)
  | inRNodeRight :
       (i : rBoolOp) (e1 e2 : rExpr),
      inRExpr n e2inRExpr n (rNode i e1 e2).
Hint Resolve inRV inRN inRNodeLeft inRNodeRight.

Theorem support :
  (f g : rNatbool) (e : rExpr),
 ( n : rNat, inRExpr n ef n = g n) → rEval f e = rEval g e.
intros f g e.
elim e; intros; simpl in |- *; auto; rewrite H; auto; rewrite H0; auto.
Qed.
Hint Resolve support.


Definition normNot (p : rExpr) :=
  match p with
  | rN p1p1
  | p1rN p1
  end.

Lemma normNotEval :
  (p : rExpr) (f : rNatbool),
 rEval f (normNot p) = negb (rEval f p).
intros; case p; simpl in |- *; auto; intros; rewrite negb_elim; auto.
Qed.

Definition normOr (p q : rExpr) :=
  match p, q with
  | rN p1, rN q1rN (rNode rAnd p1 q1)
  | rN p1, q1rN (rNode rAnd p1 (rN q1))
  | p1, rN q1rN (rNode rAnd (rN p1) q1)
  | p1, q1rN (rNode rAnd (rN p1) (rN q1))
  end.

Lemma normOrEval :
  (p q : rExpr) (f : rNatbool),
 rEval f (normOr p q) = rEval f p || rEval f q.
intros; case p; case q; intros; simpl in |- *; auto with bool;
 try rewrite de_morgan2; try rewrite negb_elim; auto.
Qed.

Definition normImpl (p q : rExpr) :=
  match p, q with
  | rN p1, rN q1rN (rNode rAnd (rN p1) q1)
  | rN p1, q1rN (rNode rAnd (rN p1) (rN q1))
  | p1, rN q1rN (rNode rAnd p1 q1)
  | p1, q1rN (rNode rAnd p1 (rN q1))
  end.

Lemma normImplEval :
  (p q : rExpr) (f : rNatbool),
 rEval f (normImpl p q) = implb (rEval f p) (rEval f q).
intros; case p; case q; intros; simpl in |- *; auto; rewrite implb_elim;
 rewrite negb_elim; auto.
Qed.

Fixpoint norm (e : Expr) : rExpr :=
  match e with
  | V nrV n
  | normalize.N pnormNot (norm p)
  | Node n1 p q
      match n1 with
      | ANdrNode rAnd (norm p) (norm q)
      | OrnormOr (norm p) (norm q)
      | ImplnormImpl (norm p) (norm q)
      | normalize.EqrNode rEq (norm p) (norm q)
      end
  end.

Theorem normEval :
  (f : rNatbool) (e : Expr), Eval f e = rEval f (norm e).
simple induction e; clear e; simpl in |- *; auto.
intros p H; rewrite normNotEval; rewrite H; auto.
intros b p Hp q Hq; case b; rewrite Hp; rewrite Hq; auto;
 rewrite normOrEval || rewrite normImplEval; auto.
Qed.


Definition Tautology (e : Expr) :=
   f : rNatbool, f zero = trueEval f e = true.

Definition rTautology (e : rExpr) :=
   f : rNatbool, f zero = truerEval f e = true.

Theorem TautoRTauto : e : Expr, Tautology e rTautology (norm e).
intros e; unfold Tautology in |- *; unfold rTautology in |- *; split.
intros H' f; rewrite <- normEval; auto.
intros H' f; rewrite normEval; auto.
Qed.