Advertisement
Guest User

Untitled

a guest
Nov 6th, 2014
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.56 KB | None | 0 0
  1. (*
  2. 02157 - Functional Programming
  3. Mandatory assignment 3: Solver for Propositional Logic
  4.  
  5. Solved by:
  6. Alexander Rosenberg Johansen
  7. s145706
  8.  
  9.  
  10. *)
  11.  
  12. (*
  13. 1. You should define a type Prop for propositions so that the following are values of type
  14. Prop:
  15. • A "p" represents the atom p,
  16. • Dis(A "p", A "q") represents the proposition p ∨ q.
  17. • Con(A "p", A "q") represents the proposition p ∧ q.
  18. • Neg(A "p") represents the proposition ¬p.
  19. *)
  20. exception Error of string
  21.  
  22. type Prop = | A of string
  23.             | Dis of Prop * Prop
  24.             | Con of Prop * Prop
  25.             | Neg of Prop
  26.  
  27. (*
  28. 2. A proposition is in negation normal form if the negation operator just appears as applied
  29. directly to atoms. Write an F# function transforming a proposition into an equivalent
  30. proposition in negation normal form, using the de Morgan laws:
  31.  
  32.     ¬(a ∧ b) is equivalent to (¬a) ∨ (¬b)
  33.     ¬(a ∨ b) is equivalent to (¬a) ∧ (¬b)
  34.  
  35. and the law: ¬(¬a) is equivalent to a.
  36. *)
  37. //dml is short for de Morgan laws
  38. let rec dml :Prop -> Prop = function
  39.     | Neg(Con(p1,p2))    -> Dis(dml (Neg(p1)), dml (Neg(p2)))   //dml case: "¬(a ∧ b) is equivalent to (¬a) ∨ (¬b)"
  40.     | Neg(Dis(p1,p2))    -> Con(dml (Neg(p1)), dml (Neg(p2)))   //dml case: "¬(a ∨ b) is equivalent to (¬a) ∧ (¬b)"
  41.     | Neg(Neg(p))        -> dml p                               //dml case: "¬(¬a) is equivalent to a"
  42.     | A(p)               -> A(p)                //Base case
  43.     | Dis(p1,p2)         -> Dis(dml p1, dml p2) //Not a "dml", branching
  44.     | Con(p1,p2)         -> Con(dml p1, dml p2) //Not a "dml", branching
  45.     | Neg(p)             -> Neg(dml p)          //Not a "dml", branching
  46.  
  47. (*
  48. 3. A literal is an atom or the negation of an atom and a basic conjunct is a conjunction
  49. of literals. A proposition is in disjunctive normal form if it is a disjunction of basic
  50. conjuncts. Write an F# function which transforms a proposition in negation normal form
  51. into an equivalent proposition in disjunctive normal form using the distributive laws:
  52.  
  53.     a ∧ (b ∨ c) is equivalent to (a ∧ b) ∨ (a ∧ c)
  54.     (a ∨ b) ∧ c is equivalent to (a ∧ c) ∨ (b ∧ c)
  55. *)
  56.  
  57. //dl is short for distributed law
  58. let rec dl :Prop -> Prop = function
  59.   //  |Con(a,Dis(b,c)) -> Dis(Con(dl a,dl b),Con(dl a,dl c))   //dl case: "a ∧ (b ∨ c) is equivalent to (a ∧ b) ∨ (a ∧ c)"
  60.   |Con(a,Dis(b,c)) -> Dis(dl (Con(a,b)), dl (Con(a,c)))
  61.   //  |Con(Dis(a,b),c) -> Dis(Con(dl a,dl c),Con(dl b,dl c))   //dl case: "(a ∨ b) ∧ c is equivalent to (a ∧ c) ∨ (b ∧ c)"
  62.   |Con(Dis(a,b),c) -> Dis(dl (Con(a,c)), dl (Con(b,c)))
  63.     |A(p)               -> A(p)             //Base case
  64.     |Dis(p1,p2)         -> Dis(dl p1,dl p2) //Not a "dl", branching
  65.     |Con(p1,p2)         -> Con(dl p1,dl p2) //Not a "dl", branching
  66.     |Neg(p)             -> Neg(dl p)        //Not a "dl", branching
  67.  
  68.  
  69.  
  70.  
  71. (*
  72. 4. We shall use a set-based representation of formulas in disjunctive normal form. Since
  73. conjunction is commutative, associative and (a ∧ a) is equivalent to a it is convenient to
  74. represent a basic conjunct bc by its set of literals litOf(bc).
  75. Similarly, we represent a disjunctive normal form formula a:
  76.  
  77.     bc1 ∨ . . . ∨ bcn
  78.  
  79. by the set
  80.  
  81.     dnfToSet(a) = {litOf(bc1), . . . , litOf(bcn)}
  82.  
  83. that we will call the dns set of a.
  84. Write F# declarations for the functions litOf and dnfToSet.
  85. *)
  86.  
  87. let rec litOf :Prop -> Set<Prop> = function
  88.     |A(p)       -> Set.ofList([A(p)])
  89.     |Neg(A(p))  -> Set.ofList([Neg(A(p))])
  90.     |Con(p1,p2) -> let setP1 = litOf p1
  91.                    let setP2 = litOf p2
  92.                    Set.union setP1 setP2
  93.     |Neg(p)     -> raise (Error("litOf cannot resolve"))  //incomplete Pattern matches
  94.     |Dis(p1,p2) -> raise (Error("litOf cannot resolve")) //incomplete Pattern matches
  95.  
  96.  
  97. let rec dnfToSet :Prop -> Set<Set<Prop>> = function
  98.     |Dis(p1,p2)  -> Set.union (dnfToSet(p1))  (dnfToSet(p2))
  99.     |Con(p1,p2)  -> Set.add (litOf (Con(p1,p2))) Set.empty
  100.     |p           -> Set.add (litOf (p)) Set.empty
  101.  
  102. (*
  103. 5. A set of literals ls (and the corresponding basic conjunct) is said to be consistent if it does
  104. not contain both literals p and ¬p for any atom p. Otherwise, ls (and the corresponding
  105. basic conjunct) is said to be inconsistent. An inconsistent basic conjunct yields false
  106. regardless of the truth values assigned to atoms. Removing it from a disjunctive normal
  107. form formula will therefore not change the meaning of that formula.
  108.  
  109. Declare an F# function isConsistent that checks the consistency of a set of literals.
  110. Declare an F# function removeInconsistent that removes inconsistent literal sets from
  111. a dns set.
  112. *)
  113.  
  114. let auxIsConsistent :Prop -> Prop = function
  115.     |A(p)       -> Neg(A(p))
  116.     |Neg(p)     -> p
  117.     |p          -> raise (Error("litOf cannot resolve"))
  118.  
  119. let rec isConsistent :Set<Prop> -> bool = function
  120.     |latSet ->  let comparisonSet = Set.foldBack(fun x set -> if Set.contains (auxIsConsistent x) (Set.remove x latSet) then Set.add x Set.empty else set) latSet Set.empty
  121.                 if Set.intersect latSet comparisonSet <> Set.empty then false else true
  122.  
  123.  
  124. let removeInconsistent :Set<Set<Prop>> -> Set<Set<Prop>> = function
  125.     |allThemLats -> Set.filter(fun x -> (isConsistent x)) allThemLats
  126.  
  127.  
  128.  
  129. (*
  130. 6. A proposition is satisfiable if it is true for some assignment of truth values to the atoms.
  131. A formula in disjunctive normal is satisfiable when one (or more) of its basic conjunctions
  132. are. Therefore, the set of satisfying assignments of a proposition can be derived from the
  133. consistent literal sets of its disjunctive normal form.
  134.  
  135. Declare an F# function toDNFsets that transforms an arbitrary proposition into a dns set
  136. with just consistent literal sets.
  137.  
  138. Declare a function impl a b for computing the implication a ⇒ b and a function iff a b
  139. for computing the bi-implication a ⇔ b.
  140. Use toDNFsets to determine the satisfying assignments for the following two formulas:
  141.  
  142. • ((¬p) ⇒ (¬q)) ⇒ (p ⇒ q)
  143. • ((¬p) ⇒ (¬q)) ⇒ (q ⇒ p)
  144.  
  145. where p and q are atoms
  146. *)
  147.  
  148. let toDNFsets :Prop -> Set<Set<Prop>> = function
  149.     |p   -> removeInconsistent (dnfToSet (dl (dml p)))
  150.  
  151. let impl :Prop*Prop -> Prop = function
  152.     |a,b -> Dis(Neg(a),b)
  153.  
  154. let iff :Prop*Prop -> Prop = function
  155.     |a,b -> Con(impl(a,b), impl(b,a))
  156.  
  157. let p = A("p")
  158. let q = A("q")
  159. let negP = Neg(p)
  160. let negQ = Neg(q)
  161.  
  162. let first1 = impl(negP,negQ)
  163. let first2 = impl(p,q)
  164. let propFirst = impl(first1,first2)
  165. let resFirst = toDNFsets propFirst
  166.  
  167. let second1 = first1
  168. let second2 = impl(q,p)
  169. let propSecond = impl(second1,second2)
  170. let resSecond = toDNFsets propSecond
  171.  
  172. (*
  173. 8: The satis ability problem for propositional logic is an NP-complete problem, and the above
  174. transformation to disjunctive normal form proposition or to a dns set has in the worst case
  175. an exponential running time.
  176. The disjunctive normal form of the following proposition:
  177.  
  178. (p1 _ q1) ^ (p2 _ q2) ^    ^ (pn _ qn) (1)
  179.  
  180. will, for example, have 2n basic conjuncts.
  181. Declare an F# function badProp n that computes the F# representation of (1).
  182. Compute toDNFsets(badProp n) for a small number of cases and check that the resulting
  183. sets indeed have 2**n elements.
  184. *)
  185. let rec badProp :int -> Prop = function
  186.     |1 -> Dis(A("p"+ string 1),A("q" + string 1))
  187.     |n -> Con(Dis(A("p" + string n),A("q" + string n)),badProp(n-1))
  188.  
  189. let testBadProp = badProp 3
  190. let testDML = dml testBadProp
  191. let testDL = dl testDML
  192. //let testDnfToSets = dnfToSet testDL
  193. //let testRemoveInconsistent = removeInconsistent testDnfToSets
  194. //let testToDNFsets = toDNFsets testBadProp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement