| 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])]  = 
 | 
| 59 |     40 |   ls.map (s => (s, ls - s))
 | 
|  |     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"
 | 
|  |    107 | val HoD = "Michael Luck"
 | 
|  |    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 | 
 | 
|  |    118 | // consider the cases for true and false
 |