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