| author | Christian Urban <christian dot urban at kcl dot ac dot uk> | 
| Tue, 12 Nov 2013 02:13:22 +0000 | |
| changeset 127 | 56cf3a9a2693 | 
| parent 65 | 8d3c4efb91b3 | 
| child 129 | 10526c967679 | 
| permissions | -rw-r--r-- | 
| 59 | 1 | |
| 60 | 2 | abstract class Term | 
| 59 | 3 | case class Var(s: String) extends Term | 
| 4 | case class Const(s: String) extends Term | |
| 5 | case class Fun(s: String, ts: List[Term]) extends Term | |
| 6 | ||
| 60 | 7 | abstract class Form {
 | 
| 8 | def -> (that: Form) = Imp(this, that) | |
| 9 | } | |
| 59 | 10 | case object True extends Form | 
| 11 | case object False extends Form | |
| 12 | case class Pred(s: String, ts: List[Term]) extends Form | |
| 13 | case class Imp(f1: Form, f2: Form) extends Form | |
| 14 | case class Says(p: String, f: Form) extends Form | |
| 15 | case class And(f1: Form, f2: Form) extends Form | |
| 16 | case class Or(f1: Form, f2: Form) extends Form | |
| 17 | ||
| 18 | case class Judgement(Gamma: List[Form], F: Form) {
 | |
| 19 | def lhs = Gamma | |
| 20 | def rhs = F | |
| 21 | } | |
| 22 | ||
| 23 | val Admin = "Admin" | |
| 24 | val Bob = "Bob" | |
| 25 | val Del = Pred("del_file", Nil)
 | |
| 26 | ||
| 27 | val Gamma = | |
| 60 | 28 | List( Says(Admin, Del) -> Del, | 
| 29 | Says(Admin, Says(Bob, Del) -> Del), | |
| 59 | 30 | Says(Bob, Del) ) | 
| 31 | ||
| 32 | val goal = Judgement(Gamma, Del) // request: provable or not? | |
| 33 | ||
| 34 | def prove(j: Judgement, sc: () => Unit) : Unit = {
 | |
| 35 | if (j.lhs.contains(j.rhs)) sc() // Axiom rule | |
| 36 | else prove1(j.lhs, j.rhs, sc) | |
| 37 | } | |
| 38 | ||
| 62 | 39 | def partitions[A](ls: List[A]): List[(A, List[A])] = | 
| 127 
56cf3a9a2693
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
65diff
changeset | 40 | ls.map (s => (s, ls diff List(s))) | 
| 59 | 41 | |
| 42 | def prove1(lhs: List[Form], rhs: Form, sc: () => Unit) : Unit = | |
| 43 |   rhs match {
 | |
| 62 | 44 | case True => sc() | 
| 45 | case False => () | |
| 59 | 46 | case Imp(f1, f2) => prove(Judgement(f1::lhs, f2), sc) | 
| 47 | case Says(p, f1) => prove(Judgement(lhs, f1), sc) | |
| 48 | case Or(f1, f2) => | |
| 49 |       { prove(Judgement(lhs, f1), sc);
 | |
| 50 | prove(Judgement(lhs, f2), sc) } | |
| 51 | case And(f1, f2) => | |
| 52 | prove(Judgement(lhs, f1), | |
| 53 | () => prove(Judgement(lhs, f2), sc)) | |
| 54 |     case _ => { for ((f, lhs_rest) <- partitions(lhs))
 | |
| 55 | prove2(f, lhs_rest, rhs, sc) } | |
| 56 | } | |
| 57 | ||
| 58 | def prove2(f: Form, lhs_rest: List[Form], rhs: Form, sc: () => Unit) : Unit = | |
| 59 |   f match {
 | |
| 62 | 60 | case True => prove(Judgement(lhs_rest, rhs), sc) | 
| 61 | case False => sc() | |
| 59 | 62 | case And(f1, f2) => | 
| 63 | prove(Judgement(f1::f2::lhs_rest, rhs), sc) | |
| 64 | case Imp(f1, f2) => | |
| 65 | prove(Judgement(lhs_rest, f1), | |
| 66 | () => prove(Judgement(f2::lhs_rest, rhs), sc)) | |
| 67 | case Or(f1, f2) => | |
| 68 | prove(Judgement(f1::lhs_rest, rhs), | |
| 69 | () => prove(Judgement(f2::lhs_rest, rhs), sc)) | |
| 70 | case Says(p, Imp(f1, f2)) => | |
| 71 | prove(Judgement(lhs_rest, Says(p, f1)), | |
| 72 | () => prove(Judgement(Says(p, f2)::lhs_rest, rhs), sc)) | |
| 73 | case _ => () | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | ||
| 78 | // function that calls prove and returns immediately once a proof is found | |
| 79 | def run (j : Judgement) : Unit = {
 | |
| 80 |   try { 
 | |
| 81 |     def sc () = { println ("Yes!"); throw new Exception }
 | |
| 82 | prove(j, sc) | |
| 83 | } | |
| 84 |   catch { case e: Exception => () }
 | |
| 85 | } | |
| 86 | ||
| 62 | 87 | run (Judgement (Nil, False -> Del)) | 
| 88 | run (Judgement (Nil, True -> Del)) | |
| 89 | run (Judgement (Nil, Del -> True)) | |
| 90 | ||
| 59 | 91 | run (goal) | 
| 92 | ||
| 62 | 93 | val Gamma1 = | 
| 94 | List( Says(Admin, Says(Bob, Del) -> Del), | |
| 95 | Says(Bob, Del) ) | |
| 96 | ||
| 97 | val goal1 = Judgement(Gamma1, Del) // not provable | |
| 98 | ||
| 99 | run (goal1) | |
| 59 | 100 | |
| 60 | 101 | run (Judgement(Nil, Del -> Del)) | 
| 59 | 102 | |
| 62 | 103 | run (Judgement(Nil, Del -> Or(False, Del))) | 
| 104 | ||
| 105 | ||
| 59 | 106 | val Chr = "Christian" | 
| 127 
56cf3a9a2693
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
65diff
changeset | 107 | val HoD = "Peter" | 
| 59 | 108 | val Email = Pred("may_btain_email", List(Const(Chr)))
 | 
| 109 | val AtLib = Pred("is_at_library", List(Const(Chr)))
 | |
| 110 | val Chr_Staff = Pred("is_staff", List(Const(Chr)))
 | |
| 111 | ||
| 60 | 112 | val Policy_HoD = Says(HoD, Chr_Staff) -> Chr_Staff | 
| 113 | val Policy_Lib = And(Chr_Staff, AtLib) -> Email | |
| 59 | 114 | val HoD_says = Says(HoD, Chr_Staff) | 
| 115 | ||
| 116 | run (Judgement (List(AtLib, Policy_HoD, Policy_Lib, HoD_says), Email)) | |
| 117 | ||
| 65 | 118 |