PropositionalLogic.scala [raw]
/* Copyright 2009-2016 EPFL, Lausanne */
import stainless.lang._
import stainless.annotation._
object PropositionalLogic {
sealed abstract class Formula
case class And(lhs: Formula, rhs: Formula) extends Formula
case class Or(lhs: Formula, rhs: Formula) extends Formula
case class Implies(lhs: Formula, rhs: Formula) extends Formula
case class Not(f: Formula) extends Formula
case class Literal(id: BigInt) extends Formula
def simplify(f: Formula): Formula = (f match {
case Implies(lhs, rhs) => Or(Not(simplify(lhs)), simplify(rhs))
case _ => f
}) ensuring(isSimplified(_))
// Counterexample for postcondition violation in `simplify`:
// when f is:
// And(Literal(8), Implies(Literal(7), Literal(6)))
def isSimplified(f: Formula): Boolean = f match {
case And(lhs, rhs) => isSimplified(lhs) && isSimplified(rhs)
case Or(lhs, rhs) => isSimplified(lhs) && isSimplified(rhs)
case Implies(_,_) => false
case Not(f) => isSimplified(f)
case Literal(_) => true
}
def isNNF(f: Formula): Boolean = f match {
case And(lhs, rhs) => isNNF(lhs) && isNNF(rhs)
case Or(lhs, rhs) => isNNF(lhs) && isNNF(rhs)
case Implies(lhs, rhs) => isNNF(lhs) && isNNF(rhs)
case Not(Literal(_)) => true
case Not(_) => false
case Literal(_) => true
}
// @induct
// def wrongCommutative(f: Formula) : Boolean = {
// nnf(simplify(f)) == simplify(nnf(f))
// }.holds
def simplifyBreaksNNF(f: Formula) : Boolean = {
require(isNNF(f))
isNNF(simplify(f))
}.holds
// Counterexample for postcondition violation in `simplifyBreaksNNF`:
// when f is:
// Implies(And(Literal(255), Literal(256)), Literal(267))
}
back