(* $Id: sol.thy,v 1.2 2004/11/23 15:14:35 webertj Exp $ Author: Stefan Berghofer, Tobias Nipkow *) header {* Representation of Propositional Formulae by Polynomials *} (*<*) theory sol imports Main begin (*>*) text {* Let the following data type for propositional formulae be given: *} datatype form = T | Var nat | And form form | Xor form form text {* Here @{term "T"} denotes a formula that is always true, @{term "Var n"} denotes a propositional variable, its name given by a natural number, @{term "And f1 f2"} denotes the AND combination, and @{term "Xor f1 f2"} the XOR (exclusive or) combination of two formulae. A constructor @{term "F"} for a formula that is always false is not necessary, since @{term "F"} can be expressed by @{term "Xor T T"}. {\bf Exercise 1:} Define a function *} consts evalf :: "(nat \ bool) \ form \ bool" text {* that evaluates a formula under a given variable assignment. *} constdefs xor :: "bool \ bool \ bool" "xor x y \ (x \ \ y) \ (\ x \ y)" primrec "evalf e T = True" "evalf e (Var i) = e i" "evalf e (And f1 f2) = (evalf e f1 \ evalf e f2)" "evalf e (Xor f1 f2) = xor (evalf e f1) (evalf e f2)" text {* Propositional formulae can be represented by so-called {\it polynomials}. A polynomial is a list of lists of propositional variables, i.e.\ an element of type @{typ "nat list list"}. The inner lists (the so-called {\it monomials}) are interpreted as conjunctive combination of variables, whereas the outer list is interpreted as exclusive-or combination of the inner lists. {\bf Exercise 2:} Define two functions *} consts evalm :: "(nat \ bool) \ nat list \ bool" evalp :: "(nat \ bool) \ nat list list \ bool" text {* for evaluation of monomials and polynomials under a given variable assignment. In particular think about how empty lists have to be evaluated. *} primrec "evalm e [] = True" "evalm e (x # xs) = (e x \ evalm e xs)" primrec "evalp e [] = False" "evalp e (m # p) = xor (evalm e m) (evalp e p)" text {* {\bf Exercise 3:} Define a function *} consts poly :: "form \ nat list list" text {* that turns a formula into a polynomial. You will need an auxiliary function *} consts mulpp :: "nat list list \ nat list list \ nat list list" text {* to ``multiply'' two polynomials, i.e.\ to compute \[ ((v^1_1 \mathbin{\odot} \cdots \mathbin{\odot} v^1_{m_1}) \mathbin{\oplus} \cdots \mathbin{\oplus} (v^k_1 \mathbin{\odot} \cdots \mathbin{\odot} v^k_{m_k})) \mathbin{\odot} ((w^1_1 \mathbin{\odot} \cdots \mathbin{\odot} w^1_{n_1}) \mathbin{\oplus} \cdots \mathbin{\oplus} (w^l_1 \mathbin{\odot} \cdots \mathbin{\odot} w^l_{n_l})) \] where $\mathbin{\oplus}$ denotes ``exclusive or'', and $\mathbin{\odot}$ denotes ``and''. This is done using the usual calculation rules for addition and multiplication. *} primrec "mulpp [] q = []" "mulpp (m # p) q = map (op @ m) q @ (mulpp p q)" primrec "poly T = [[]]" "poly (Var i) = [[i]]" "poly (Xor f1 f2) = poly f1 @ poly f2" "poly (And f1 f2) = mulpp (poly f1) (poly f2)" text {* {\bf Exercise 4:} Now show correctness of your function @{term "poly"}: *} theorem poly_correct: "evalf e f = evalp e (poly f)" (*<*) oops (*>*) text {* It is useful to prove a similar correctness theorem for @{term "mulpp"} first. *} lemma evalm_app: "evalm e (xs @ ys) = (evalm e xs \ evalm e ys)" apply (induct xs) apply auto done lemma evalp_app: "evalp e (xs @ ys) = (xor (evalp e xs) (evalp e ys))" apply (induct xs) apply (auto simp add: xor_def) done theorem mulmp_correct: "evalp e (map (op @ m) p) = (evalm e m \ evalp e p)" apply (induct p) apply (auto simp add: xor_def evalm_app) done theorem mulpp_correct: "evalp e (mulpp p q) = (evalp e p \ evalp e q)" apply (induct p) apply (auto simp add: xor_def mulmp_correct evalp_app) done theorem poly_correct: "evalf e f = evalp e (poly f)" apply (induct f) apply (auto simp add: xor_def mulpp_correct evalp_app) done (*<*) end (*>*)