Skip to content

Commit

Permalink
Some tweaks to propositional logic benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
vkuncak committed Oct 28, 2024
1 parent 2024a36 commit 97fa07c
Showing 1 changed file with 49 additions and 34 deletions.
83 changes: 49 additions & 34 deletions frontends/benchmarks/verification/valid/PropositionalLogic.scala
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
/* Copyright 2009-2021 EPFL, Lausanne */
/* Copyright 2009-2024 EPFL, Lausanne */

import stainless.lang._
import stainless.annotation._
import stainless.lang.*
import stainless.annotation.*

object PropositionalLogic {
object PropositionalLogic:

sealed abstract class Formula
sealed abstract class Formula:
def size: BigInt = {
this match
case And(l, r) => l.size + r.size + 1
case Or(l, r) => l.size + r.size + 1
case Not(f) => f.size + 1 // bad negation, bad!
case Implies(l, r) => l.size + r.size + 1 // why does false imply true?!
case Literal(_) => BigInt(1)
}.ensuring(res => res >= 1)

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: Int) extends Formula

def simplify(f: Formula): Formula = (f match {
case And(lhs, rhs) => And(simplify(lhs), simplify(rhs))
case Or(lhs, rhs) => Or(simplify(lhs), simplify(rhs))
case Implies(lhs, rhs) => Or(Not(simplify(lhs)), simplify(rhs))
case Not(f) => Not(simplify(f))
case Literal(_) => f
}).ensuring(isSimplified(_))
def simplify(f: Formula): Formula = {
f match
case And(lhs, rhs) => And(simplify(lhs), simplify(rhs))
case Or(lhs, rhs) => Or(simplify(lhs), simplify(rhs))
case Implies(lhs, rhs) => Or(Not(simplify(lhs)), simplify(rhs))
case Not(f) => Not(simplify(f))
case Literal(_) => f
}.ensuring(isSimplified(_))

def isSimplified(f: Formula): Boolean = f match {
case And(lhs, rhs) => isSimplified(lhs) && isSimplified(rhs)
Expand All @@ -28,39 +38,41 @@ object PropositionalLogic {
case Literal(_) => true
}

def nnf(formula: Formula): Formula = (formula match {
case And(lhs, rhs) => And(nnf(lhs), nnf(rhs))
case Or(lhs, rhs) => Or(nnf(lhs), nnf(rhs))
case Implies(lhs, rhs) => Implies(nnf(lhs), nnf(rhs))
case Not(And(lhs, rhs)) => Or(nnf(Not(lhs)), nnf(Not(rhs)))
case Not(Or(lhs, rhs)) => And(nnf(Not(lhs)), nnf(Not(rhs)))
case Not(Implies(lhs, rhs)) => And(nnf(lhs), nnf(Not(rhs)))
case Not(Not(f)) => nnf(f)
case Not(Literal(_)) => formula
case Literal(_) => formula
}).ensuring(isNNF(_))
def nnf(formula: Formula): Formula = {
require(isSimplified(formula))
decreases(formula.size)
formula match
case And(lhs, rhs) => And(nnf(lhs), nnf(rhs))
case Or(lhs, rhs) => Or(nnf(lhs), nnf(rhs))
case Not(And(lhs, rhs)) => Or(nnf(Not(lhs)), nnf(Not(rhs)))
case Not(Or(lhs, rhs)) => And(nnf(Not(lhs)), nnf(Not(rhs)))
case Not(Implies(lhs, rhs)) => And(nnf(lhs), nnf(Not(rhs)))
case Not(Not(f)) => nnf(f)
case Not(Literal(_)) => formula
case Literal(_) => formula
}.ensuring(isNNF(_))

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
}
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) => false
case Not(Literal(_)) => true
case Not(_) => false
case Literal(_) => true
}.ensuring(res => !res || isSimplified(f))

def vars(f: Formula): Set[Int] = {
require(isNNF(f))
f match {
case And(lhs, rhs) => vars(lhs) ++ vars(rhs)
case Or(lhs, rhs) => vars(lhs) ++ vars(rhs)
case Implies(lhs, rhs) => vars(lhs) ++ vars(rhs)
case Not(Literal(i)) => Set[Int](i)
case Literal(i) => Set[Int](i)
}
}

def fv(f : Formula) = { vars(nnf(f)) }
def fv(f : Formula) = { vars(nnf(simplify(f))) }

@induct
def nnfIsStable(f: Formula) : Boolean = {
Expand All @@ -73,4 +85,7 @@ object PropositionalLogic {
require(isSimplified(f))
simplify(f) == f
}.holds
}


end PropositionalLogic

0 comments on commit 97fa07c

Please sign in to comment.