From 018e2a8af8bf8ecc40254d6ecab45583aea8ee94 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Fri, 12 Feb 2016 18:36:15 +0100 Subject: [PATCH] Add current benchmarks, new benchmark List[T].indexOfOpt with variants --- testcases/synthesis/PrimeHeuristic.scala.off | 11 -- .../{ => archives}/ADTInduction.scala | 0 .../synthesis/{ => archives}/BinaryTree.scala | 0 .../{ => archives}/CegisExamples.scala | 0 .../{ => archives}/CegisFunctions.scala | 0 .../{ => archives}/ChooseArith.scala | 0 .../synthesis/{ => archives}/ChooseIneq.scala | 0 .../synthesis/{ => archives}/ChoosePos.scala | 0 .../{ => archives}/ChurchNumerals.scala | 0 .../synthesis/{ => archives}/DrSuter.scala | 0 .../synthesis/{ => archives}/FastExp.scala | 0 .../synthesis/{ => archives}/FiniteSort.scala | 0 .../synthesis/{ => archives}/Injection.scala | 0 .../synthesis/{ => archives}/InnerSplit.scala | 0 .../synthesis/{ => archives}/Justify.scala | 0 .../synthesis/{ => archives}/Matching.scala | 0 .../{ => archives}/ScaleWeight.scala | 0 .../synthesis/{ => archives}/Sec2Time.scala | 0 .../{ => archives}/SimplestCegis.scala | 0 testcases/synthesis/{ => archives}/Spt.scala | 0 .../{ => archives}/Unification.scala | 0 .../synthesis/{ => archives}/ZuneBug.scala | 0 .../synthesis/current/AddressBook/Make.scala | 66 ++++++++ .../synthesis/current/AddressBook/Merge.scala | 69 +++++++++ .../current/BatchedQueue/Dequeue.scala | 80 ++++++++++ .../current/BatchedQueue/Enqueue.scala | 83 ++++++++++ .../synthesis/current/Compiler/Desugar.scala | 118 ++++++++++++++ .../current/Compiler/DesugarImplies.scala | 144 ++++++++++++++++++ .../current/Compiler/RewriteImplies.scala | 124 +++++++++++++++ .../current/Compiler/RewriteMinus.scala | 107 +++++++++++++ testcases/synthesis/current/List/Delete.scala | 26 ++++ testcases/synthesis/current/List/Diff.scala | 50 ++++++ .../synthesis/current/List/IndexOfInt.scala | 67 ++++++++ .../synthesis/current/List/IndexOfOpt.scala | 65 ++++++++ .../synthesis/current/List/IndexOfOpt2.scala | 67 ++++++++ testcases/synthesis/current/List/Insert.scala | 28 ++++ testcases/synthesis/current/List/Split.scala | 37 +++++ testcases/synthesis/current/List/Union.scala | 37 +++++ .../synthesis/current/Parentheses/Par.scala | 54 +++++++ .../synthesis/current/SortedList/Delete.scala | 34 +++++ .../synthesis/current/SortedList/Diff.scala | 53 +++++++ .../synthesis/current/SortedList/Insert.scala | 34 +++++ .../current/SortedList/InsertAlways.scala | 34 +++++ .../current/SortedList/InsertionSort.scala | 49 ++++++ .../current/SortedList/MergeSort.scala | 62 ++++++++ .../current/SortedList/MergeSortGuided.scala | 68 +++++++++ .../synthesis/current/SortedList/Union.scala | 51 +++++++ .../current/StrictSortedList/Delete.scala | 34 +++++ .../current/StrictSortedList/Insert.scala | 34 +++++ .../current/StrictSortedList/Union.scala | 51 +++++++ .../synthesis/current/UnaryNumerals/Add.scala | 21 +++ .../current/UnaryNumerals/Distinct.scala | 30 ++++ .../current/UnaryNumerals/Mult.scala | 30 ++++ testcases/synthesis/current/run.sh | 43 ++++++ 54 files changed, 1850 insertions(+), 11 deletions(-) delete mode 100644 testcases/synthesis/PrimeHeuristic.scala.off rename testcases/synthesis/{ => archives}/ADTInduction.scala (100%) rename testcases/synthesis/{ => archives}/BinaryTree.scala (100%) rename testcases/synthesis/{ => archives}/CegisExamples.scala (100%) rename testcases/synthesis/{ => archives}/CegisFunctions.scala (100%) rename testcases/synthesis/{ => archives}/ChooseArith.scala (100%) rename testcases/synthesis/{ => archives}/ChooseIneq.scala (100%) rename testcases/synthesis/{ => archives}/ChoosePos.scala (100%) rename testcases/synthesis/{ => archives}/ChurchNumerals.scala (100%) rename testcases/synthesis/{ => archives}/DrSuter.scala (100%) rename testcases/synthesis/{ => archives}/FastExp.scala (100%) rename testcases/synthesis/{ => archives}/FiniteSort.scala (100%) rename testcases/synthesis/{ => archives}/Injection.scala (100%) rename testcases/synthesis/{ => archives}/InnerSplit.scala (100%) rename testcases/synthesis/{ => archives}/Justify.scala (100%) rename testcases/synthesis/{ => archives}/Matching.scala (100%) rename testcases/synthesis/{ => archives}/ScaleWeight.scala (100%) rename testcases/synthesis/{ => archives}/Sec2Time.scala (100%) rename testcases/synthesis/{ => archives}/SimplestCegis.scala (100%) rename testcases/synthesis/{ => archives}/Spt.scala (100%) rename testcases/synthesis/{ => archives}/Unification.scala (100%) rename testcases/synthesis/{ => archives}/ZuneBug.scala (100%) create mode 100644 testcases/synthesis/current/AddressBook/Make.scala create mode 100644 testcases/synthesis/current/AddressBook/Merge.scala create mode 100644 testcases/synthesis/current/BatchedQueue/Dequeue.scala create mode 100644 testcases/synthesis/current/BatchedQueue/Enqueue.scala create mode 100644 testcases/synthesis/current/Compiler/Desugar.scala create mode 100644 testcases/synthesis/current/Compiler/DesugarImplies.scala create mode 100644 testcases/synthesis/current/Compiler/RewriteImplies.scala create mode 100644 testcases/synthesis/current/Compiler/RewriteMinus.scala create mode 100644 testcases/synthesis/current/List/Delete.scala create mode 100644 testcases/synthesis/current/List/Diff.scala create mode 100644 testcases/synthesis/current/List/IndexOfInt.scala create mode 100644 testcases/synthesis/current/List/IndexOfOpt.scala create mode 100644 testcases/synthesis/current/List/IndexOfOpt2.scala create mode 100644 testcases/synthesis/current/List/Insert.scala create mode 100644 testcases/synthesis/current/List/Split.scala create mode 100644 testcases/synthesis/current/List/Union.scala create mode 100644 testcases/synthesis/current/Parentheses/Par.scala create mode 100644 testcases/synthesis/current/SortedList/Delete.scala create mode 100644 testcases/synthesis/current/SortedList/Diff.scala create mode 100644 testcases/synthesis/current/SortedList/Insert.scala create mode 100644 testcases/synthesis/current/SortedList/InsertAlways.scala create mode 100644 testcases/synthesis/current/SortedList/InsertionSort.scala create mode 100644 testcases/synthesis/current/SortedList/MergeSort.scala create mode 100644 testcases/synthesis/current/SortedList/MergeSortGuided.scala create mode 100644 testcases/synthesis/current/SortedList/Union.scala create mode 100644 testcases/synthesis/current/StrictSortedList/Delete.scala create mode 100644 testcases/synthesis/current/StrictSortedList/Insert.scala create mode 100644 testcases/synthesis/current/StrictSortedList/Union.scala create mode 100644 testcases/synthesis/current/UnaryNumerals/Add.scala create mode 100644 testcases/synthesis/current/UnaryNumerals/Distinct.scala create mode 100644 testcases/synthesis/current/UnaryNumerals/Mult.scala create mode 100755 testcases/synthesis/current/run.sh diff --git a/testcases/synthesis/PrimeHeuristic.scala.off b/testcases/synthesis/PrimeHeuristic.scala.off deleted file mode 100644 index 31a689935..000000000 --- a/testcases/synthesis/PrimeHeuristic.scala.off +++ /dev/null @@ -1,11 +0,0 @@ -import leon.lang._ - -object PrimeHeuristic { - def maybePrime(n: Int): Boolean = n match { - case 2 * k => false - case 3 * k => false - case 6 * k - 1 => true - case 6 * k + 1 => true - } - -} diff --git a/testcases/synthesis/ADTInduction.scala b/testcases/synthesis/archives/ADTInduction.scala similarity index 100% rename from testcases/synthesis/ADTInduction.scala rename to testcases/synthesis/archives/ADTInduction.scala diff --git a/testcases/synthesis/BinaryTree.scala b/testcases/synthesis/archives/BinaryTree.scala similarity index 100% rename from testcases/synthesis/BinaryTree.scala rename to testcases/synthesis/archives/BinaryTree.scala diff --git a/testcases/synthesis/CegisExamples.scala b/testcases/synthesis/archives/CegisExamples.scala similarity index 100% rename from testcases/synthesis/CegisExamples.scala rename to testcases/synthesis/archives/CegisExamples.scala diff --git a/testcases/synthesis/CegisFunctions.scala b/testcases/synthesis/archives/CegisFunctions.scala similarity index 100% rename from testcases/synthesis/CegisFunctions.scala rename to testcases/synthesis/archives/CegisFunctions.scala diff --git a/testcases/synthesis/ChooseArith.scala b/testcases/synthesis/archives/ChooseArith.scala similarity index 100% rename from testcases/synthesis/ChooseArith.scala rename to testcases/synthesis/archives/ChooseArith.scala diff --git a/testcases/synthesis/ChooseIneq.scala b/testcases/synthesis/archives/ChooseIneq.scala similarity index 100% rename from testcases/synthesis/ChooseIneq.scala rename to testcases/synthesis/archives/ChooseIneq.scala diff --git a/testcases/synthesis/ChoosePos.scala b/testcases/synthesis/archives/ChoosePos.scala similarity index 100% rename from testcases/synthesis/ChoosePos.scala rename to testcases/synthesis/archives/ChoosePos.scala diff --git a/testcases/synthesis/ChurchNumerals.scala b/testcases/synthesis/archives/ChurchNumerals.scala similarity index 100% rename from testcases/synthesis/ChurchNumerals.scala rename to testcases/synthesis/archives/ChurchNumerals.scala diff --git a/testcases/synthesis/DrSuter.scala b/testcases/synthesis/archives/DrSuter.scala similarity index 100% rename from testcases/synthesis/DrSuter.scala rename to testcases/synthesis/archives/DrSuter.scala diff --git a/testcases/synthesis/FastExp.scala b/testcases/synthesis/archives/FastExp.scala similarity index 100% rename from testcases/synthesis/FastExp.scala rename to testcases/synthesis/archives/FastExp.scala diff --git a/testcases/synthesis/FiniteSort.scala b/testcases/synthesis/archives/FiniteSort.scala similarity index 100% rename from testcases/synthesis/FiniteSort.scala rename to testcases/synthesis/archives/FiniteSort.scala diff --git a/testcases/synthesis/Injection.scala b/testcases/synthesis/archives/Injection.scala similarity index 100% rename from testcases/synthesis/Injection.scala rename to testcases/synthesis/archives/Injection.scala diff --git a/testcases/synthesis/InnerSplit.scala b/testcases/synthesis/archives/InnerSplit.scala similarity index 100% rename from testcases/synthesis/InnerSplit.scala rename to testcases/synthesis/archives/InnerSplit.scala diff --git a/testcases/synthesis/Justify.scala b/testcases/synthesis/archives/Justify.scala similarity index 100% rename from testcases/synthesis/Justify.scala rename to testcases/synthesis/archives/Justify.scala diff --git a/testcases/synthesis/Matching.scala b/testcases/synthesis/archives/Matching.scala similarity index 100% rename from testcases/synthesis/Matching.scala rename to testcases/synthesis/archives/Matching.scala diff --git a/testcases/synthesis/ScaleWeight.scala b/testcases/synthesis/archives/ScaleWeight.scala similarity index 100% rename from testcases/synthesis/ScaleWeight.scala rename to testcases/synthesis/archives/ScaleWeight.scala diff --git a/testcases/synthesis/Sec2Time.scala b/testcases/synthesis/archives/Sec2Time.scala similarity index 100% rename from testcases/synthesis/Sec2Time.scala rename to testcases/synthesis/archives/Sec2Time.scala diff --git a/testcases/synthesis/SimplestCegis.scala b/testcases/synthesis/archives/SimplestCegis.scala similarity index 100% rename from testcases/synthesis/SimplestCegis.scala rename to testcases/synthesis/archives/SimplestCegis.scala diff --git a/testcases/synthesis/Spt.scala b/testcases/synthesis/archives/Spt.scala similarity index 100% rename from testcases/synthesis/Spt.scala rename to testcases/synthesis/archives/Spt.scala diff --git a/testcases/synthesis/Unification.scala b/testcases/synthesis/archives/Unification.scala similarity index 100% rename from testcases/synthesis/Unification.scala rename to testcases/synthesis/archives/Unification.scala diff --git a/testcases/synthesis/ZuneBug.scala b/testcases/synthesis/archives/ZuneBug.scala similarity index 100% rename from testcases/synthesis/ZuneBug.scala rename to testcases/synthesis/archives/ZuneBug.scala diff --git a/testcases/synthesis/current/AddressBook/Make.scala b/testcases/synthesis/current/AddressBook/Make.scala new file mode 100644 index 000000000..612effe38 --- /dev/null +++ b/testcases/synthesis/current/AddressBook/Make.scala @@ -0,0 +1,66 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object AddressBookMake { + + case class Address[A](info: A, priv: Boolean) + + sealed abstract class AddressList[A] { + def size: BigInt = { + this match { + case Nil() => BigInt(0) + case Cons(head, tail) => BigInt(1) + tail.size + } + } ensuring { res => res >= 0 } + + def content: Set[Address[A]] = this match { + case Nil() => Set[Address[A]]() + case Cons(addr, l1) => Set(addr) ++ l1.content + } + } + + case class Cons[A](a: Address[A], tail: AddressList[A]) extends AddressList[A] + case class Nil[A]() extends AddressList[A] + + def allPersonal[A](l: AddressList[A]): Boolean = l match { + case Nil() => true + case Cons(a, l1) => + if (a.priv) allPersonal(l1) + else false + } + + def allBusiness[A](l: AddressList[A]): Boolean = l match { + case Nil() => true + case Cons(a, l1) => + if (a.priv) false + else allBusiness(l1) + } + + case class AddressBook[A](business: AddressList[A], personal: AddressList[A]) { + def size: BigInt = business.size + personal.size + + def content: Set[Address[A]] = business.content ++ personal.content + + def invariant = { + allPersonal(personal) && allBusiness(business) + } + } + + def makeAddressBook[A](as: AddressList[A]): AddressBook[A] = { + choose( (res: AddressBook[A]) => res.content == as.content && res.invariant ) + + /* as match { + case Nil() => AddressBook[A](Nil[A](), Nil[A]()) + case Cons(x, xs) => + val AddressBook(b, p) = makeAddressBook(xs) + if(x.priv) AddressBook(b, Cons(x, p)) + else AddressBook(Cons(x, b), p) + } + + } ensuring { + res => res.content == as.content && res.invariant */ + } + + +} diff --git a/testcases/synthesis/current/AddressBook/Merge.scala b/testcases/synthesis/current/AddressBook/Merge.scala new file mode 100644 index 000000000..92a5b5bfe --- /dev/null +++ b/testcases/synthesis/current/AddressBook/Merge.scala @@ -0,0 +1,69 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object AddressBookMake { + + case class Address[A](info: A, priv: Boolean) + + sealed abstract class AddressList[A] { + def size: BigInt = { + this match { + case Nil() => BigInt(0) + case Cons(head, tail) => BigInt(1) + tail.size + } + } ensuring { res => res >= 0 } + + def content: Set[Address[A]] = this match { + case Nil() => Set[Address[A]]() + case Cons(addr, l1) => Set(addr) ++ l1.content + } + + def ++(that: AddressList[A]): AddressList[A] = { + this match { + case Cons(h, t) => Cons(h, t ++ that) + case Nil() => that + } + } ensuring { + res => res.content == this.content ++ that.content + } + } + + case class Cons[A](a: Address[A], tail: AddressList[A]) extends AddressList[A] + case class Nil[A]() extends AddressList[A] + + def allPersonal[A](l: AddressList[A]): Boolean = l match { + case Nil() => true + case Cons(a, l1) => + if (a.priv) allPersonal(l1) + else false + } + + def allBusiness[A](l: AddressList[A]): Boolean = l match { + case Nil() => true + case Cons(a, l1) => + if (a.priv) false + else allBusiness(l1) + } + + case class AddressBook[A](business: AddressList[A], personal: AddressList[A]) { + def size: BigInt = business.size + personal.size + + def content: Set[Address[A]] = business.content ++ personal.content + + @inline + def invariant = { + allPersonal(personal) && allBusiness(business) + } + } + + def merge[A](a1: AddressBook[A], a2: AddressBook[A]): AddressBook[A] = { + require(a1.invariant && a2.invariant) + + choose( (res: AddressBook[A]) => + res.personal.content == (a1.personal.content ++ a2.personal.content) && + res.business.content == (a1.business.content ++ a2.business.content) && + res.invariant + ) + } +} diff --git a/testcases/synthesis/current/BatchedQueue/Dequeue.scala b/testcases/synthesis/current/BatchedQueue/Dequeue.scala new file mode 100644 index 000000000..c44fc0628 --- /dev/null +++ b/testcases/synthesis/current/BatchedQueue/Dequeue.scala @@ -0,0 +1,80 @@ +import leon.lang._ +import leon.lang.synthesis._ + +object BatchedQueue { + sealed abstract class List[T] { + def content: Set[T] = { + this match { + case Cons(h, t) => Set(h) ++ t.content + case Nil() => Set() + } + } + + def size: BigInt = { + this match { + case Cons(h, t) => BigInt(1) + t.size + case Nil() => BigInt(0) + } + } ensuring { _ >= 0 } + + def reverse: List[T] = { + this match { + case Cons(h, t) => t.reverse.append(Cons(h, Nil[T]())) + case Nil() => Nil[T]() + } + } ensuring { res => + this.content == res.content + } + + def append(r: List[T]): List[T] = { + this match { + case Cons(h, t) => Cons(h, t.append(r)) + case Nil() => r + } + } + + def isEmpty: Boolean = { + this == Nil[T]() + } + + def tail: List[T] = { + require(this != Nil[T]()) + this match { + case Cons(h, t) => t + } + } + + def head: T = { + require(this != Nil[T]()) + this match { + case Cons(h, t) => h + } + } + } + + case class Cons[T](h: T, t: List[T]) extends List[T] + case class Nil[T]() extends List[T] + + case class Queue[T](f: List[T], r: List[T]) { + def content: Set[T] = f.content ++ r.content + def size: BigInt = f.size + r.size + + def isEmpty: Boolean = f.isEmpty && r.isEmpty + + def invariant: Boolean = { + (f.isEmpty) ==> (r.isEmpty) + } + + def toList: List[T] = f.append(r.reverse) + + def dequeue: Queue[T] = { + require(invariant && !isEmpty) + + choose { (res: Queue[T]) => + res.size == size-1 && res.toList == this.toList.tail && res.invariant + } + } + } + + val test = Queue[BigInt](Cons(42, Nil()), Nil()).dequeue +} diff --git a/testcases/synthesis/current/BatchedQueue/Enqueue.scala b/testcases/synthesis/current/BatchedQueue/Enqueue.scala new file mode 100644 index 000000000..0f30a5ba1 --- /dev/null +++ b/testcases/synthesis/current/BatchedQueue/Enqueue.scala @@ -0,0 +1,83 @@ +import leon.lang._ +import leon.lang.synthesis._ + +object BatchedQueue { + sealed abstract class List[T] { + def content: Set[T] = { + this match { + case Cons(h, t) => Set(h) ++ t.content + case Nil() => Set() + } + } + + def size: BigInt = { + this match { + case Cons(h, t) => BigInt(1) + t.size + case Nil() => BigInt(0) + } + } ensuring { _ >= 0 } + + def reverse: List[T] = { + this match { + case Cons(h, t) => t.reverse.append(Cons(h, Nil[T]())) + case Nil() => Nil[T]() + } + } ensuring { res => + this.content == res.content + } + + def append(r: List[T]): List[T] = { + this match { + case Cons(h, t) => Cons(h, t.append(r)) + case Nil() => r + } + } + + def tail: List[T] = { + require(this != Nil[T]()) + this match { + case Cons(h, t) => t + } + } + + def head: T = { + require(this != Nil[T]()) + this match { + case Cons(h, t) => h + } + } + + def last: T = { + require(this != Nil[T]()) + this match { + case Cons(h, Nil()) => h + case Cons(h, t) => t.last + } + } + } + + case class Cons[T](h: T, t: List[T]) extends List[T] + case class Nil[T]() extends List[T] + + case class Queue[T](f: List[T], r: List[T]) { + def content: Set[T] = f.content ++ r.content + def size: BigInt = f.size + r.size + + def invariant: Boolean = { + (f == Nil[T]()) ==> (r == Nil[T]()) + } + + def toList: List[T] = f.append(r.reverse) + + def enqueue(v: T): Queue[T] = { + require(invariant) + + ???[Queue[T]] + } ensuring { (res: Queue[T]) => + res.invariant && + res.toList.last == v && + res.size == size + 1 && + res.content == this.content ++ Set(v) + } + } +} diff --git a/testcases/synthesis/current/Compiler/Desugar.scala b/testcases/synthesis/current/Compiler/Desugar.scala new file mode 100644 index 000000000..2684c71b2 --- /dev/null +++ b/testcases/synthesis/current/Compiler/Desugar.scala @@ -0,0 +1,118 @@ +import leon.lang._ +import leon.lang.synthesis._ +import leon._ + +object Compiler { + abstract class Expr + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class UMinus(e: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Implies(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Not(e : Expr) extends Expr + case class Eq(lhs: Expr, rhs: Expr) extends Expr + case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr + case class BoolLiteral(b : Boolean) extends Expr + case class IntLiteral(i: BigInt) extends Expr + + abstract class Value + case class BoolValue(b: Boolean) extends Value + case class IntValue(i: BigInt) extends Value + case object Error extends Value + + def eval(e: Expr): Value = e match { + case Plus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il+ir) + case _ => Error + } + + case Minus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il-ir) + case _ => Error + } + + case UMinus(l) => + eval(l) match { + case IntValue(b) => IntValue(-b) + case _ => Error + } + + case LessThan(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il < ir) + case _ => Error + } + + case And(l, r) => + eval(l) match { + case b @ BoolValue(false) => b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Or(l, r) => + eval(l) match { + case b @ BoolValue(true) => + b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Implies(l, r) => + eval(l) match { + case b @ BoolValue(true) => + eval(r) + case b @ BoolValue(false) => + BoolValue(true) + case _ => Error + } + + case Not(l) => + eval(l) match { + case BoolValue(b) => BoolValue(!b) + case _ => Error + } + + case Eq(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il == ir) + case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir) + case _ => Error + } + + case Ite(c, t, e) => + eval(c) match { + case BoolValue(true) => eval(t) + case BoolValue(false) => eval(t) + case _ => Error + } + + case IntLiteral(l) => IntValue(l) + case BoolLiteral(b) => BoolValue(b) + } + + def rewriteMinus(in: Minus): Expr = { + choose{ (out: Expr) => + eval(in) == eval(out) && !(out.isInstanceOf[Minus]) + } + } + + def rewriteImplies(in: Implies): Expr = { + choose{ (out: Expr) => + eval(in) == eval(out) && !(out.isInstanceOf[Implies]) + } + } + + + def plop(x: Expr) = { + eval(x) == Error//eval(Not(IntLiteral(BigInt(2)))) + }.holds +} diff --git a/testcases/synthesis/current/Compiler/DesugarImplies.scala b/testcases/synthesis/current/Compiler/DesugarImplies.scala new file mode 100644 index 000000000..de5c544ff --- /dev/null +++ b/testcases/synthesis/current/Compiler/DesugarImplies.scala @@ -0,0 +1,144 @@ +import leon.lang._ +import leon.lang.synthesis._ +import leon._ + +object Compiler { + abstract class Expr + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class UMinus(e: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Implies(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Not(e : Expr) extends Expr + case class Eq(lhs: Expr, rhs: Expr) extends Expr + case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr + case class BoolLiteral(b : Boolean) extends Expr + case class IntLiteral(i: BigInt) extends Expr + + def exists(e: Expr, f: Expr => Boolean): Boolean = { + f(e) || (e match { + case Plus(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Minus(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case LessThan(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case And(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Or(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Implies(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Eq(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Ite(c, t, e) => exists(c, f) || exists(t, f) || exists(e, f) + case Not(e) => exists(e, f) + case UMinus(e) => exists(e, f) + case _ => false + }) + } + + abstract class Value + case class BoolValue(b: Boolean) extends Value + case class IntValue(i: BigInt) extends Value + case object Error extends Value + + def eval(e: Expr): Value = e match { + case Plus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il+ir) + case _ => Error + } + + case Minus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il-ir) + case _ => Error + } + + case UMinus(l) => + eval(l) match { + case IntValue(b) => IntValue(-b) + case _ => Error + } + + case LessThan(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il < ir) + case _ => Error + } + + case And(l, r) => + eval(l) match { + case b @ BoolValue(false) => b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Or(l, r) => + eval(l) match { + case b @ BoolValue(true) => + b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Implies(l, r) => + eval(l) match { + case b @ BoolValue(true) => + eval(r) + case b @ BoolValue(false) => + BoolValue(true) + case _ => Error + } + + case Not(l) => + eval(l) match { + case BoolValue(b) => BoolValue(!b) + case _ => Error + } + + case Eq(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il == ir) + case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir) + case _ => Error + } + + case Ite(c, t, e) => + eval(c) match { + case BoolValue(true) => eval(t) + case BoolValue(false) => eval(t) + case _ => Error + } + + case IntLiteral(l) => IntValue(l) + case BoolLiteral(b) => BoolValue(b) + } + + + //def desugar(e: Expr): Expr = { + // choose{ (out: Expr) => + // eval(e) == eval(out) && !exists(out, f => f.isInstanceOf[Implies]) + // } + //} + + def desugar(e: Expr): Expr = { + e match { + case Plus(lhs, rhs) => Plus(desugar(lhs), desugar(rhs)) + case Minus(lhs, rhs) => Minus(desugar(lhs), desugar(rhs)) + case LessThan(lhs, rhs) => LessThan(desugar(lhs), desugar(rhs)) + case And(lhs, rhs) => And(desugar(lhs), desugar(rhs)) + case Or(lhs, rhs) => Or(desugar(lhs), desugar(rhs)) + case Implies(lhs, rhs) => //Implies(desugar(lhs), desugar(rhs)) + Or(Not(desugar(lhs)), desugar(rhs)) + case Eq(lhs, rhs) => Eq(desugar(lhs), desugar(rhs)) + case Ite(c, t, e) => Ite(desugar(c), desugar(t), desugar(e)) + case Not(e) => Not(desugar(e)) + case UMinus(e) => UMinus(desugar(e)) + case e => e + } + } ensuring { out => + //eval(e) == eval(out) && + !exists(out, f => f.isInstanceOf[Implies]) + } +} diff --git a/testcases/synthesis/current/Compiler/RewriteImplies.scala b/testcases/synthesis/current/Compiler/RewriteImplies.scala new file mode 100644 index 000000000..4b50b9cbe --- /dev/null +++ b/testcases/synthesis/current/Compiler/RewriteImplies.scala @@ -0,0 +1,124 @@ +import leon.lang._ +import leon.lang.synthesis._ +import leon._ + +object Compiler { + abstract class Expr + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class UMinus(e: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Implies(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Not(e : Expr) extends Expr + case class Eq(lhs: Expr, rhs: Expr) extends Expr + case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr + case class BoolLiteral(b : Boolean) extends Expr + case class IntLiteral(i: BigInt) extends Expr + + def exists(e: Expr, f: Expr => Boolean): Boolean = { + f(e) || (e match { + case Plus(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Minus(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case LessThan(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case And(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Or(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Implies(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Eq(lhs, rhs) => exists(lhs, f) || exists(rhs, f) + case Ite(c, t, e) => exists(c, f) || exists(t, f) || exists(e, f) + case Not(e) => exists(e, f) + case UMinus(e) => exists(e, f) + case _ => false + }) + } + + abstract class Value + case class BoolValue(b: Boolean) extends Value + case class IntValue(i: BigInt) extends Value + case object Error extends Value + + def eval(e: Expr): Value = e match { + case Plus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il+ir) + case _ => Error + } + + case Minus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il-ir) + case _ => Error + } + + case UMinus(l) => + eval(l) match { + case IntValue(b) => IntValue(-b) + case _ => Error + } + + case LessThan(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il < ir) + case _ => Error + } + + case And(l, r) => + eval(l) match { + case b @ BoolValue(false) => b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Or(l, r) => + eval(l) match { + case b @ BoolValue(true) => + b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Implies(l, r) => + eval(l) match { + case b @ BoolValue(true) => + eval(r) + case b @ BoolValue(false) => + BoolValue(true) + case _ => Error + } + + case Not(l) => + eval(l) match { + case BoolValue(b) => BoolValue(!b) + case _ => Error + } + + case Eq(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il == ir) + case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir) + case _ => Error + } + + case Ite(c, t, e) => + eval(c) match { + case BoolValue(true) => eval(t) + case BoolValue(false) => eval(t) + case _ => Error + } + + case IntLiteral(l) => IntValue(l) + case BoolLiteral(b) => BoolValue(b) + } + + + def desugar(in: Expr): Expr = { + choose{ (out: Expr) => + eval(in) == eval(out) && !(out.isInstanceOf[Implies]) + } + } +} diff --git a/testcases/synthesis/current/Compiler/RewriteMinus.scala b/testcases/synthesis/current/Compiler/RewriteMinus.scala new file mode 100644 index 000000000..de2fa4360 --- /dev/null +++ b/testcases/synthesis/current/Compiler/RewriteMinus.scala @@ -0,0 +1,107 @@ +import leon.lang._ +import leon.lang.synthesis._ +import leon._ + +object Compiler { + abstract class Expr + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class UMinus(e: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Implies(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Not(e : Expr) extends Expr + case class Eq(lhs: Expr, rhs: Expr) extends Expr + case class Ite(cond: Expr, thn: Expr, els: Expr) extends Expr + case class BoolLiteral(b : Boolean) extends Expr + case class IntLiteral(i: BigInt) extends Expr + + abstract class Value + case class BoolValue(b: Boolean) extends Value + case class IntValue(i: BigInt) extends Value + case object Error extends Value + + def eval(e: Expr): Value = e match { + case Plus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il+ir) + case _ => Error + } + + case Minus(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => IntValue(il-ir) + case _ => Error + } + + case UMinus(l) => + eval(l) match { + case IntValue(b) => IntValue(-b) + case _ => Error + } + + case LessThan(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il < ir) + case _ => Error + } + + case And(l, r) => + eval(l) match { + case b @ BoolValue(false) => b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Or(l, r) => + eval(l) match { + case b @ BoolValue(true) => + b + case b: BoolValue => + eval(r) + case _ => + Error + } + + case Implies(l, r) => + eval(l) match { + case b @ BoolValue(true) => + eval(r) + case b @ BoolValue(false) => + BoolValue(true) + case _ => Error + } + + case Not(l) => + eval(l) match { + case BoolValue(b) => BoolValue(!b) + case _ => Error + } + + case Eq(l, r) => + (eval(l), eval(r)) match { + case (IntValue(il), IntValue(ir)) => BoolValue(il == ir) + case (BoolValue(il), BoolValue(ir)) => BoolValue(il == ir) + case _ => Error + } + + case Ite(c, t, e) => + eval(c) match { + case BoolValue(true) => eval(t) + case BoolValue(false) => eval(t) + case _ => Error + } + + case IntLiteral(l) => IntValue(l) + case BoolLiteral(b) => BoolValue(b) + } + + def rewriteMinus(in: Minus): Expr = { + choose{ (out: Expr) => + eval(in) == eval(out) && !(out.isInstanceOf[Minus]) + } + } +} diff --git a/testcases/synthesis/current/List/Delete.scala b/testcases/synthesis/current/List/Delete.scala new file mode 100644 index 000000000..30716c591 --- /dev/null +++ b/testcases/synthesis/current/List/Delete.scala @@ -0,0 +1,26 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object Delete { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def delete(in: List, v: BigInt) = { + ???[List] + } ensuring { + (out : List) => + content(out) == content(in) -- Set(v) + } +} diff --git a/testcases/synthesis/current/List/Diff.scala b/testcases/synthesis/current/List/Diff.scala new file mode 100644 index 000000000..9fb3ade95 --- /dev/null +++ b/testcases/synthesis/current/List/Diff.scala @@ -0,0 +1,50 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object Diff { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List) : BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def insert(in1: List, v: BigInt): List = { + Cons(v, in1) + } ensuring { content(_) == content(in1) ++ Set(v) } + + def delete(in1: List, v: BigInt): List = { + in1 match { + case Cons(h,t) => + if (h == v) { + delete(t, v) + } else { + Cons(h, delete(t, v)) + } + case Nil => + Nil + } + } ensuring { content(_) == content(in1) -- Set(v) } + + // def diff(in1: List, in2: List): List = { + // in2 match { + // case Nil => + // in1 + // case Cons(h, t) => + // diff(delete(in1, h), t) + // } + // } ensuring { content(_) == content(in1) -- content(in2) } + + def diff(in1: List, in2: List) = choose { + (out : List) => + content(out) == content(in1) -- content(in2) + } +} diff --git a/testcases/synthesis/current/List/IndexOfInt.scala b/testcases/synthesis/current/List/IndexOfInt.scala new file mode 100644 index 000000000..595d40cf3 --- /dev/null +++ b/testcases/synthesis/current/List/IndexOfInt.scala @@ -0,0 +1,67 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object IndexOf { + sealed abstract class List[T] { + def size: BigInt = { + this match { + case Nil() => BigInt(0) + case Cons(_, t) => BigInt(1) + t.size + } + } ensuring { + res => res >= 0 + } + + def content: Set[T] = this match { + case Nil() => Set.empty[T] + case Cons(i, t) => Set(i) ++ t.content + } + + def apply(i: BigInt): T = { + require(i >= 0 && i < size) + this match { + case Cons(h, t) => + if (i == 0) { + h + } else { + t.apply(i-1) + } + } + } ensuring { e => + content contains e + } + + def indexOfInt(e: T): BigInt = { + ???[BigInt] + + //this match { + // case Cons(h, t) => + // val r = t.indexOfInt(e) + + // if (e == h) { + // BigInt(0) + // } else { + // if (r < 0) { + // r + // } else { + // r + 1 + // } + // } + // case Nil() => + // BigInt(-1) + //} + + } ensuring { res => + if (res < 0) { + !(content contains e) + } else { + res < size && apply(res) == e + } + } + } + + case class Cons[T](head: T, tail: List[T]) extends List[T] + case class Nil[T]() extends List[T] + +} diff --git a/testcases/synthesis/current/List/IndexOfOpt.scala b/testcases/synthesis/current/List/IndexOfOpt.scala new file mode 100644 index 000000000..6738e5c23 --- /dev/null +++ b/testcases/synthesis/current/List/IndexOfOpt.scala @@ -0,0 +1,65 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object IndexOf { + sealed abstract class List[T] { + def size: BigInt = { + this match { + case Nil() => BigInt(0) + case Cons(_, t) => BigInt(1) + t.size + } + } ensuring { + res => res >= 0 + } + + def content: Set[T] = this match { + case Nil() => Set.empty[T] + case Cons(i, t) => Set(i) ++ t.content + } + + def apply(i: BigInt): T = { + require(i >= 0 && i < size) + this match { + case Cons(h, t) => + if (i == 0) { + h + } else { + t.apply(i-1) + } + } + } ensuring { e => + content contains e + } + + def indexOfOpt(e: T): Option[BigInt] = { + ???[Option[BigInt]] + /* + this match { + case Cons(h, t) => + val r = t.indexOfOpt(e) + + if (e == h) { + Some(BigInt(0)) + } else { + r match { + case Some(i) => Some(i+1) + case None() => None[BigInt]() + } + } + case Nil() => + None[BigInt]() + } + */ + } ensuring { res => + res match { + case None() => !(content contains e) + case Some(i) => i >= 0 && i < size && apply(i) == e + } + } + } + + case class Cons[T](head: T, tail: List[T]) extends List[T] + case class Nil[T]() extends List[T] + +} diff --git a/testcases/synthesis/current/List/IndexOfOpt2.scala b/testcases/synthesis/current/List/IndexOfOpt2.scala new file mode 100644 index 000000000..ff85f7a1c --- /dev/null +++ b/testcases/synthesis/current/List/IndexOfOpt2.scala @@ -0,0 +1,67 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object IndexOf { + sealed abstract class List[T] { + def size: BigInt = { + this match { + case Nil() => BigInt(0) + case Cons(_, t) => BigInt(1) + t.size + } + } ensuring { + res => res >= 0 + } + + def content: Set[T] = this match { + case Nil() => Set.empty[T] + case Cons(i, t) => Set(i) ++ t.content + } + + def apply(i: BigInt): T = { + require(i >= 0 && i < size) + this match { + case Cons(h, t) => + if (i == 0) { + h + } else { + t.apply(i-1) + } + } + } ensuring { e => + content contains e + } + + def indexOfOpt(e: T, offset: BigInt): Option[BigInt] = { + ???[Option[BigInt]] + /* + this match { + case Cons(h, t) => + val r = t.indexOfOpt(e) + + if (e == h) { + Some(BigInt(0)) + } else { + r match { + case Some(i) => Some(i+1) + case None() => None[BigInt]() + } + } + case Nil() => + None[BigInt]() + } + */ + } ensuring { res => + res match { + case None() => !(content contains e) + case Some(r) => + val i = r - offset; + i >= 0 && i < size && apply(i) == e + } + } + } + + case class Cons[T](head: T, tail: List[T]) extends List[T] + case class Nil[T]() extends List[T] + +} diff --git a/testcases/synthesis/current/List/Insert.scala b/testcases/synthesis/current/List/Insert.scala new file mode 100644 index 000000000..48c38f4df --- /dev/null +++ b/testcases/synthesis/current/List/Insert.scala @@ -0,0 +1,28 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object Insert { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List) : BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + //def insert(in1: List, v: BigInt): List = { + // Cons(v, in1) + //} ensuring { content(_) == content(in1) ++ Set(v) } + + def insert(in1: List, v: BigInt) = choose { + (out : List) => + content(out) == content(in1) ++ Set(v) + } +} diff --git a/testcases/synthesis/current/List/Split.scala b/testcases/synthesis/current/List/Split.scala new file mode 100644 index 000000000..f37e68264 --- /dev/null +++ b/testcases/synthesis/current/List/Split.scala @@ -0,0 +1,37 @@ +/* Copyright 2009-2015 EPFL, Lausanne */ + +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object Complete { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List) : BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def splitSpec(list : List, res : (List,List)) : Boolean = { + val s1 = size(res._1) + val s2 = size(res._2) + abs(s1 - s2) <= 1 && s1 + s2 == size(list) && + content(res._1) ++ content(res._2) == content(list) + } + + def abs(i : BigInt) : BigInt = { + if(i < 0) -i else i + } ensuring(_ >= 0) + + def split(list : List) : (List,List) = { + choose { (res : (List,List)) => splitSpec(list, res) } + } + +} diff --git a/testcases/synthesis/current/List/Union.scala b/testcases/synthesis/current/List/Union.scala new file mode 100644 index 000000000..d6a5fa579 --- /dev/null +++ b/testcases/synthesis/current/List/Union.scala @@ -0,0 +1,37 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object Union { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List) : BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1)+ size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def insert(in1: List, v: BigInt): List = { + Cons(v, in1) + } ensuring { content(_) == content(in1) ++ Set(v) } + + // def union(in1: List, in2: List): List = { + // in1 match { + // case Cons(h, t) => + // Cons(h, union(t, in2)) + // case Nil => + // in2 + // } + // } ensuring { content(_) == content(in1) ++ content(in2) } + + def union(in1: List, in2: List) = choose { + (out : List) => + content(out) == content(in1) ++ content(in2) + } +} diff --git a/testcases/synthesis/current/Parentheses/Par.scala b/testcases/synthesis/current/Parentheses/Par.scala new file mode 100644 index 000000000..b91213086 --- /dev/null +++ b/testcases/synthesis/current/Parentheses/Par.scala @@ -0,0 +1,54 @@ +import leon.lang._ +import leon.lang.synthesis._ +import leon.collection._ + + +object MatchPar { + abstract class AbsChar + case object OP extends AbsChar + case object CP extends AbsChar + case object NA extends AbsChar + + def matchPar(l: List[AbsChar]): BigInt = { + + ???[BigInt] + /* + l match { + case Nil() => 0 + case Cons(h, t) => + val rec = matchPar(t) + h match { + case OP => 1 + rec + case CP => if (rec <= 0) { + -1 + } else { + rec - 1 + } + case NA => rec + } + }*/ + } ensuring { res => + ((count(OP, l) != count(CP, l)) ==> (res != 0)) && + ((l, res) passes { + case Nil() => 0 + case Cons(OP, Cons(CP, Nil())) => 0 + case Cons(CP, Cons(OP, _)) => -1 + case Cons(OP, Cons(OP, Nil())) => 2 + case Cons(OP, Cons(OP, Cons(CP, Cons(CP, Cons(OP, Cons(CP, Nil())))))) => 0 + }) + } + + def count[T](a: T, l: List[T]): BigInt = { + l match { + case Cons(h, t) => + if (h == a) { + 1 + count(a, t) + } else { + count(a, t) + } + case Nil() => BigInt(0) + } + } ensuring { (res: BigInt) => + res >= 0 + } +} diff --git a/testcases/synthesis/current/SortedList/Delete.scala b/testcases/synthesis/current/SortedList/Delete.scala new file mode 100644 index 000000000..788f232d3 --- /dev/null +++ b/testcases/synthesis/current/SortedList/Delete.scala @@ -0,0 +1,34 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListDelete { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def delete(in: List, v: BigInt) = { + require(isSorted(in)) + + choose( (res : List) => + (content(res) == content(in) -- Set(v)) && isSorted(res) + ) + } +} diff --git a/testcases/synthesis/current/SortedList/Diff.scala b/testcases/synthesis/current/SortedList/Diff.scala new file mode 100644 index 000000000..d391b85ba --- /dev/null +++ b/testcases/synthesis/current/SortedList/Diff.scala @@ -0,0 +1,53 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListDiff { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def delete(in1: List, v: BigInt): List = { + require(isSorted(in1)) + in1 match { + case Cons(h,t) => + if (h < v) { + Cons(h, delete(t, v)) + } else if (h == v) { + delete(t, v) + } else { + in1 + } + case Nil => + Nil + } + } ensuring { res => content(res) == content(in1) -- Set(v) && isSorted(res) } + + + def diff(in1: List, in2: List) = { + require(isSorted(in1) && isSorted(in2)) + + choose { + (out : List) => + (content(out) == content(in1) -- content(in2)) && isSorted(out) + } + } + +} diff --git a/testcases/synthesis/current/SortedList/Insert.scala b/testcases/synthesis/current/SortedList/Insert.scala new file mode 100644 index 000000000..0bf80d1e9 --- /dev/null +++ b/testcases/synthesis/current/SortedList/Insert.scala @@ -0,0 +1,34 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListInsert { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insert(in1: List, v: BigInt): List = { + require(isSorted(in1)) + + choose { (out : List) => + (content(out) == content(in1) ++ Set(v)) && isSorted(out) + } + } +} diff --git a/testcases/synthesis/current/SortedList/InsertAlways.scala b/testcases/synthesis/current/SortedList/InsertAlways.scala new file mode 100644 index 000000000..73e0b240d --- /dev/null +++ b/testcases/synthesis/current/SortedList/InsertAlways.scala @@ -0,0 +1,34 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListInsertAlways { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insertAlways(in1: List, v: BigInt) = { + require(isSorted(in1)) + + choose{ (out : List) => + (content(out) == content(in1) ++ Set(v)) && isSorted(out) && size(out) == size(in1) + 1 + } + } +} diff --git a/testcases/synthesis/current/SortedList/InsertionSort.scala b/testcases/synthesis/current/SortedList/InsertionSort.scala new file mode 100644 index 000000000..0752ad33f --- /dev/null +++ b/testcases/synthesis/current/SortedList/InsertionSort.scala @@ -0,0 +1,49 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListInsertionSort { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insert(in1: List, v: BigInt): List = { + require(isSorted(in1)) + in1 match { + case Cons(h, t) => + if (v < h) { + Cons(v, in1) + } else if (v == h) { + in1 + } else { + Cons(h, insert(t, v)) + } + case Nil => + Cons(v, Nil) + } + + } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) } + + def insertionSort(in1: List): List = { + choose { (out: List) => + content(out) == content(in1) && isSorted(out) + } + } +} diff --git a/testcases/synthesis/current/SortedList/MergeSort.scala b/testcases/synthesis/current/SortedList/MergeSort.scala new file mode 100644 index 000000000..7a285c146 --- /dev/null +++ b/testcases/synthesis/current/SortedList/MergeSort.scala @@ -0,0 +1,62 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListUnion { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def split(in: List): (List, List) = { + in match { + case Cons(h1, Cons(h2, t)) => + val r = split(t) + (Cons(h1, r._1), Cons(h2, r._2)) + case Cons(h1, Nil) => + (in, Nil) + case Nil => + (Nil, Nil) + } + } + + def merge(in1: List, in2: List): List = { + require(isSorted(in1) && isSorted(in2)) + (in1, in2) match { + case (Cons(h1, t1), Cons(h2, t2)) => + if (h1 < h2) { + Cons(h1, merge(t1, in2)) + } else { + Cons(h2, merge(in1, t2)) + } + case (l, Nil) => l + case (Nil, l) => l + } + } ensuring { + (out : List) => + (content(out) == content(in1) ++ content(in2)) && isSorted(out) + } + + def sort(in: List): List = { + ???[List] + } ensuring { + (out : List) => + content(out) == content(in) && isSorted(out) + } +} diff --git a/testcases/synthesis/current/SortedList/MergeSortGuided.scala b/testcases/synthesis/current/SortedList/MergeSortGuided.scala new file mode 100644 index 000000000..0035eceea --- /dev/null +++ b/testcases/synthesis/current/SortedList/MergeSortGuided.scala @@ -0,0 +1,68 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListUnion { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def split(in: List): (List, List) = { + in match { + case Cons(h1, Cons(h2, t)) => + val r = split(t) + (Cons(h1, r._1), Cons(h2, r._2)) + case Cons(h1, Nil) => + (in, Nil) + case Nil => + (Nil, Nil) + } + } + + def merge(in1: List, in2: List): List = { + require(isSorted(in1) && isSorted(in2)) + (in1, in2) match { + case (Cons(h1, t1), Cons(h2, t2)) => + if (h1 < h2) { + Cons(h1, merge(t1, in2)) + } else { + Cons(h2, merge(in1, t2)) + } + case (l, Nil) => l + case (Nil, l) => l + } + } ensuring { + (out : List) => + (content(out) == content(in1) ++ content(in2)) && isSorted(out) + } + + def sort(in: List): List = { + in match { + case Cons(h1, Cons(h2, t)) => + val s = split(in) + merge(sort(s._1), sort(s._2)) + case _ => + ???[List] + } + } ensuring { + (out : List) => + content(out) == content(in) && isSorted(out) + } +} diff --git a/testcases/synthesis/current/SortedList/Union.scala b/testcases/synthesis/current/SortedList/Union.scala new file mode 100644 index 000000000..d3f11adcc --- /dev/null +++ b/testcases/synthesis/current/SortedList/Union.scala @@ -0,0 +1,51 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object SortedListUnion { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 > x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insert(in1: List, v: BigInt): List = { + require(isSorted(in1)) + in1 match { + case Cons(h, t) => + if (v < h) { + Cons(v, in1) + } else if (v == h) { + in1 + } else { + Cons(h, insert(t, v)) + } + case Nil => + Cons(v, Nil) + } + + } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) } + + def union(in1: List, in2: List) = { + require(isSorted(in1) && isSorted(in2)) + choose { + (out : List) => + (content(out) == content(in1) ++ content(in2)) && isSorted(out) + } + } +} diff --git a/testcases/synthesis/current/StrictSortedList/Delete.scala b/testcases/synthesis/current/StrictSortedList/Delete.scala new file mode 100644 index 000000000..23999d96c --- /dev/null +++ b/testcases/synthesis/current/StrictSortedList/Delete.scala @@ -0,0 +1,34 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object StrictSortedListDelete { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def delete(in: List, v: BigInt) = { + require(isSorted(in)) + + choose( (res : List) => + (content(res) == content(in) -- Set(v)) && isSorted(res) + ) + } +} diff --git a/testcases/synthesis/current/StrictSortedList/Insert.scala b/testcases/synthesis/current/StrictSortedList/Insert.scala new file mode 100644 index 000000000..65f3c01f9 --- /dev/null +++ b/testcases/synthesis/current/StrictSortedList/Insert.scala @@ -0,0 +1,34 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object StrictSortedListInsert { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insert(in1: List, v: BigInt): List = { + require(isSorted(in1)) + + choose { (out : List) => + (content(out) == content(in1) ++ Set(v)) && isSorted(out) + } + } +} diff --git a/testcases/synthesis/current/StrictSortedList/Union.scala b/testcases/synthesis/current/StrictSortedList/Union.scala new file mode 100644 index 000000000..c10ed419d --- /dev/null +++ b/testcases/synthesis/current/StrictSortedList/Union.scala @@ -0,0 +1,51 @@ +import leon.annotation._ +import leon.lang._ +import leon.lang.synthesis._ + +object StrictSortedListUnion { + sealed abstract class List + case class Cons(head: BigInt, tail: List) extends List + case object Nil extends List + + def size(l: List): BigInt = (l match { + case Nil => BigInt(0) + case Cons(_, t) => BigInt(1) + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[BigInt] = l match { + case Nil => Set.empty[BigInt] + case Cons(i, t) => Set(i) ++ content(t) + } + + def isSorted(list: List): Boolean = list match { + case Nil => true + case Cons(_, Nil) => true + case Cons(x1, Cons(x2, _)) if(x1 >= x2) => false + case Cons(_, xs) => isSorted(xs) + } + + def insert(in1: List, v: BigInt): List = { + require(isSorted(in1)) + in1 match { + case Cons(h, t) => + if (v < h) { + Cons(v, in1) + } else if (v == h) { + in1 + } else { + Cons(h, insert(t, v)) + } + case Nil => + Cons(v, Nil) + } + + } ensuring { res => (content(res) == content(in1) ++ Set(v)) && isSorted(res) } + + def union(in1: List, in2: List) = { + require(isSorted(in1) && isSorted(in2)) + choose { + (out : List) => + (content(out) == content(in1) ++ content(in2)) && isSorted(out) + } + } +} diff --git a/testcases/synthesis/current/UnaryNumerals/Add.scala b/testcases/synthesis/current/UnaryNumerals/Add.scala new file mode 100644 index 000000000..a34d1834f --- /dev/null +++ b/testcases/synthesis/current/UnaryNumerals/Add.scala @@ -0,0 +1,21 @@ +import leon.lang._ +import leon.lang.synthesis._ + +object UnaryNumeralsAdd { + sealed abstract class Num + case object Z extends Num + case class S(pred: Num) extends Num + + def value(n: Num): BigInt = { + n match { + case Z => BigInt(0) + case S(p) => BigInt(1) + value(p) + } + } ensuring (_ >= 0) + + def add(x: Num, y: Num): Num = { + choose { (r : Num) => + value(r) == value(x) + value(y) + } + } +} diff --git a/testcases/synthesis/current/UnaryNumerals/Distinct.scala b/testcases/synthesis/current/UnaryNumerals/Distinct.scala new file mode 100644 index 000000000..4287378d1 --- /dev/null +++ b/testcases/synthesis/current/UnaryNumerals/Distinct.scala @@ -0,0 +1,30 @@ +import leon.lang._ +import leon.lang.synthesis._ + +object UnaryNumeralsDistinct { + sealed abstract class Num + case object Z extends Num + case class S(pred: Num) extends Num + + def value(n: Num): BigInt = { + n match { + case Z => BigInt(0) + case S(p) => BigInt(1) + value(p) + } + } ensuring (_ >= 0) + + def add(x: Num, y: Num): Num = { + x match { + case S(p) => S(add(p, y)) + case Z => y + } + } ensuring { (r : Num) => + value(r) == value(x) + value(y) + } + + def distinct(x: Num, y: Num): Num = { + choose { (r : Num) => + r != x && r != y + } + } +} diff --git a/testcases/synthesis/current/UnaryNumerals/Mult.scala b/testcases/synthesis/current/UnaryNumerals/Mult.scala new file mode 100644 index 000000000..bfa39365e --- /dev/null +++ b/testcases/synthesis/current/UnaryNumerals/Mult.scala @@ -0,0 +1,30 @@ +import leon.lang._ +import leon.lang.synthesis._ + +object UnaryNumeralsMult { + sealed abstract class Num + case object Z extends Num + case class S(pred: Num) extends Num + + def value(n: Num): BigInt = { + n match { + case Z => BigInt(0) + case S(p) => BigInt(1) + value(p) + } + } ensuring (_ >= 0) + + def add(x: Num, y: Num): Num = { + x match { + case S(p) => S(add(p, y)) + case Z => y + } + } ensuring { (r : Num) => + value(r) == value(x) + value(y) + } + + def mult(x: Num, y: Num): Num = { + choose { (r : Num) => + value(r) == value(x) * value(y) + } + } +} diff --git a/testcases/synthesis/current/run.sh b/testcases/synthesis/current/run.sh new file mode 100755 index 000000000..522e432df --- /dev/null +++ b/testcases/synthesis/current/run.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +function run { + cmd="./leon --debug=report --timeout=30 --synthesis --cegis:maxsize=7 $1" + echo "Running " $cmd + echo "------------------------------------------------------------------------------------------------------------------" + $cmd; +} + +echo "==================================================================================================================" >> synthesis-report.txt +# These are all the benchmarks included in my thesis +# List +run testcases/synthesis/current/List/Insert.scala +run testcases/synthesis/current/List/Delete.scala +run testcases/synthesis/current/List/Union.scala +run testcases/synthesis/current/List/Diff.scala +run testcases/synthesis/current/List/Split.scala + +# SortedList +run testcases/synthesis/current/SortedList/Insert.scala +run testcases/synthesis/current/SortedList/InsertAlways.scala +run testcases/synthesis/current/SortedList/Delete.scala +run testcases/synthesis/current/SortedList/Union.scala +run testcases/synthesis/current/SortedList/Diff.scala +run testcases/synthesis/current/SortedList/InsertionSort.scala + +# StrictSortedList +run testcases/synthesis/current/StrictSortedList/Insert.scala +run testcases/synthesis/current/StrictSortedList/Delete.scala +run testcases/synthesis/current/StrictSortedList/Union.scala + +# UnaryNumerals +run testcases/synthesis/current/UnaryNumerals/Add.scala +run testcases/synthesis/current/UnaryNumerals/Distinct.scala +run testcases/synthesis/current/UnaryNumerals/Mult.scala + +# BatchedQueue +run testcases/synthesis/current/BatchedQueue/Enqueue.scala +run testcases/synthesis/current/BatchedQueue/Dequeue.scala + +# AddressBook +run testcases/synthesis/current/AddressBook/Make.scala +run testcases/synthesis/current/AddressBook/Merge.scala -- GitLab