diff --git a/src/purescala/Common.scala b/src/purescala/Common.scala index a528df50db387cdc6799c14040c61753259efec3..fb01de0f1f1e53b7603f49ad3344b806f7dbb93c 100644 --- a/src/purescala/Common.scala +++ b/src/purescala/Common.scala @@ -48,7 +48,7 @@ object Common { def apply(name: String, alwaysShowUniqueID: Boolean = false) : Identifier = new Identifier(name, UniqueCounter.next, alwaysShowUniqueID) } - trait ScalacPositional { + @serializable trait ScalacPositional { self => private var prow: Int = -1078 diff --git a/src/purescala/Definitions.scala b/src/purescala/Definitions.scala index 9faaa6b03db2f8be9951e51251c53fd03b767b55..2384edf71847be45e377a62bf212c17a96129dee 100644 --- a/src/purescala/Definitions.scala +++ b/src/purescala/Definitions.scala @@ -5,24 +5,35 @@ object Definitions { import Trees._ import TypeTrees._ - sealed abstract class Definition { + @serializable sealed abstract class Definition { val id: Identifier override def toString: String = PrettyPrinter(this) + override def hashCode : Int = id.hashCode + override def equals(that : Any) : Boolean = that match { + case t : Definition => t.id == this.id + case _ => false + } } /** A VarDecl declares a new identifier to be of a certain type. */ - case class VarDecl(id: Identifier, tpe: TypeTree) extends Typed { + @serializable case class VarDecl(id: Identifier, tpe: TypeTree) extends Typed { override def getType = tpe override def setType(tt: TypeTree) = scala.Predef.error("Can't set type of VarDecl.") + override def hashCode : Int = id.hashCode + override def equals(that : Any) : Boolean = that match { + case t : VarDecl => t.id == this.id + case _ => false + } + def toVariable : Variable = Variable(id).setType(tpe) } - type VarDecls = Seq[VarDecl] + @serializable type VarDecls = Seq[VarDecl] /** A wrapper for a program. For now a program is simply a single object. The * name is meaningless and we just use the package name as id. */ - case class Program(id: Identifier, mainObject: ObjectDef) extends Definition { + @serializable case class Program(id: Identifier, mainObject: ObjectDef) extends Definition { def definedFunctions = mainObject.definedFunctions def definedClasses = mainObject.definedClasses def classHierarchyRoots = mainObject.classHierarchyRoots @@ -40,7 +51,7 @@ object Definitions { /** Objects work as containers for class definitions, functions (def's) and * val's. */ - case class ObjectDef(id: Identifier, defs : Seq[Definition], invariants: Seq[Expr]) extends Definition { + @serializable case class ObjectDef(id: Identifier, defs : Seq[Definition], invariants: Seq[Expr]) extends Definition { lazy val definedFunctions : Seq[FunDef] = defs.filter(_.isInstanceOf[FunDef]).map(_.asInstanceOf[FunDef]) lazy val definedClasses : Seq[ClassTypeDef] = defs.filter(_.isInstanceOf[ClassTypeDef]).map(_.asInstanceOf[ClassTypeDef]) @@ -127,7 +138,7 @@ object Definitions { /** Useful because case classes and classes are somewhat unified in some * patterns (of pattern-matching, that is) */ - sealed trait ClassTypeDef extends Definition { + @serializable sealed trait ClassTypeDef extends Definition { self => val id: Identifier @@ -135,11 +146,12 @@ object Definitions { def setParent(parent: AbstractClassDef) : self.type def hasParent: Boolean = parent.isDefined val isAbstract: Boolean + } /** Will be used at some point as a common ground for case classes (which * implicitely define extractors) and explicitely defined unapply methods. */ - sealed trait ExtractorTypeDef + @serializable sealed trait ExtractorTypeDef /** Abstract classes. */ object AbstractClassDef { @@ -228,7 +240,7 @@ object Definitions { //} /** Values */ - case class ValDef(varDecl: VarDecl, value: Expr) extends Definition { + @serializable case class ValDef(varDecl: VarDecl, value: Expr) extends Definition { val id: Identifier = varDecl.id } @@ -251,7 +263,7 @@ object Definitions { def hasBody = hasImplementation def hasPrecondition : Boolean = precondition.isDefined def hasPostcondition : Boolean = postcondition.isDefined - + private var annots: Set[String] = Set.empty[String] def addAnnotation(as: String*) : FunDef = { annots = annots ++ as diff --git a/src/purescala/FairZ3Solver.scala b/src/purescala/FairZ3Solver.scala index 7e62e89965e7ea9702afedd0b1652da97a091cf2..c26e46adf5e16da3e1b812c6bf6dbc370932c02e 100644 --- a/src/purescala/FairZ3Solver.scala +++ b/src/purescala/FairZ3Solver.scala @@ -11,6 +11,7 @@ import scala.collection.mutable.{Map => MutableMap} import scala.collection.mutable.{Set => MutableSet} class FairZ3Solver(val reporter: Reporter) extends Solver(reporter) with AbstractZ3Solver with Z3ModelReconstruction { + // have to comment this to use the solver for constraint solving... // assert(Settings.useFairInstantiator) private final val UNKNOWNASSAT : Boolean = false diff --git a/src/purescala/Trees.scala b/src/purescala/Trees.scala index ee4f69d10b986d6ba9f5fbd9ba6b31deae18fe4a..3e037816931f9a2443386d5035a53827142ae284 100644 --- a/src/purescala/Trees.scala +++ b/src/purescala/Trees.scala @@ -8,21 +8,21 @@ object Trees { /* EXPRESSIONS */ - sealed abstract class Expr extends Typed { + @serializable sealed abstract class Expr extends Typed { override def toString: String = PrettyPrinter(this) } - sealed trait Terminal { + @serializable sealed trait Terminal { self: Expr => } /* This describes computational errors (unmatched case, taking min of an * empty set, division by zero, etc.). It should always be typed according to * the expected type. */ - case class Error(description: String) extends Expr with Terminal with ScalacPositional + @serializable case class Error(description: String) extends Expr with Terminal with ScalacPositional /* Like vals */ - case class Let(binder: Identifier, value: Expr, body: Expr) extends Expr { + @serializable case class Let(binder: Identifier, value: Expr, body: Expr) extends Expr { binder.markAsLetBinder val et = body.getType if(et != Untyped) @@ -30,10 +30,10 @@ object Trees { } /* Control flow */ - case class FunctionInvocation(funDef: FunDef, args: Seq[Expr]) extends Expr with FixedType with ScalacPositional { + @serializable case class FunctionInvocation(funDef: FunDef, args: Seq[Expr]) extends Expr with FixedType with ScalacPositional { val fixedType = funDef.returnType } - case class IfExpr(cond: Expr, then: Expr, elze: Expr) extends Expr + @serializable case class IfExpr(cond: Expr, then: Expr, elze: Expr) extends Expr object MatchExpr { def apply(scrutinee: Expr, cases: Seq[MatchCase]) : MatchExpr = { @@ -54,7 +54,7 @@ object Trees { def scrutineeClassType: ClassType = scrutinee.getType.asInstanceOf[ClassType] } - sealed abstract class MatchCase { + @serializable sealed abstract class MatchCase { val pattern: Pattern val rhs: Expr val theGuard: Option[Expr] @@ -62,29 +62,29 @@ object Trees { def expressions: Seq[Expr] } - case class SimpleCase(pattern: Pattern, rhs: Expr) extends MatchCase { + @serializable case class SimpleCase(pattern: Pattern, rhs: Expr) extends MatchCase { val theGuard = None def expressions = List(rhs) } - case class GuardedCase(pattern: Pattern, guard: Expr, rhs: Expr) extends MatchCase { + @serializable case class GuardedCase(pattern: Pattern, guard: Expr, rhs: Expr) extends MatchCase { val theGuard = Some(guard) def expressions = List(guard, rhs) } - sealed abstract class Pattern { + @serializable sealed abstract class Pattern { val subPatterns: Seq[Pattern] val binder: Option[Identifier] private def subBinders = subPatterns.map(_.binders).foldLeft[Set[Identifier]](Set.empty)(_ ++ _) def binders: Set[Identifier] = subBinders ++ (if(binder.isDefined) Set(binder.get) else Set.empty) } - case class InstanceOfPattern(binder: Option[Identifier], classTypeDef: ClassTypeDef) extends Pattern { // c: Class + @serializable case class InstanceOfPattern(binder: Option[Identifier], classTypeDef: ClassTypeDef) extends Pattern { // c: Class val subPatterns = Seq.empty } - case class WildcardPattern(binder: Option[Identifier]) extends Pattern { // c @ _ + @serializable case class WildcardPattern(binder: Option[Identifier]) extends Pattern { // c @ _ val subPatterns = Seq.empty } - case class CaseClassPattern(binder: Option[Identifier], caseClassDef: CaseClassDef, subPatterns: Seq[Pattern]) extends Pattern + @serializable case class CaseClassPattern(binder: Option[Identifier], caseClassDef: CaseClassDef, subPatterns: Seq[Pattern]) extends Pattern // case class ExtractorPattern(binder: Option[Identifier], // extractor : ExtractorTypeDef, // subPatterns: Seq[Pattern]) extends Pattern // c @ Extractor(...,...) @@ -164,7 +164,7 @@ object Trees { val fixedType = BooleanType } - case class Not(expr: Expr) extends Expr with FixedType { + @serializable case class Not(expr: Expr) extends Expr with FixedType { val fixedType = BooleanType } @@ -196,63 +196,63 @@ object Trees { val fixedType = BooleanType } - case class Variable(id: Identifier) extends Expr with Terminal { + @serializable case class Variable(id: Identifier) extends Expr with Terminal { override def getType = id.getType override def setType(tt: TypeTree) = { id.setType(tt); this } } // represents the result in post-conditions - case class ResultVariable() extends Expr with Terminal + @serializable case class ResultVariable() extends Expr with Terminal /* Literals */ - sealed abstract class Literal[T] extends Expr with Terminal { + @serializable sealed abstract class Literal[T] extends Expr with Terminal { val value: T } - case class IntLiteral(value: Int) extends Literal[Int] with FixedType { + @serializable case class IntLiteral(value: Int) extends Literal[Int] with FixedType { val fixedType = Int32Type } - case class BooleanLiteral(value: Boolean) extends Literal[Boolean] with FixedType { + @serializable case class BooleanLiteral(value: Boolean) extends Literal[Boolean] with FixedType { val fixedType = BooleanType } - case class StringLiteral(value: String) extends Literal[String] + @serializable case class StringLiteral(value: String) extends Literal[String] - case class CaseClass(classDef: CaseClassDef, args: Seq[Expr]) extends Expr with FixedType { + @serializable case class CaseClass(classDef: CaseClassDef, args: Seq[Expr]) extends Expr with FixedType { val fixedType = CaseClassType(classDef) } - case class CaseClassInstanceOf(classDef: CaseClassDef, expr: Expr) extends Expr with FixedType { + @serializable case class CaseClassInstanceOf(classDef: CaseClassDef, expr: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class CaseClassSelector(classDef: CaseClassDef, caseClass: Expr, selector: Identifier) extends Expr with FixedType { + @serializable case class CaseClassSelector(classDef: CaseClassDef, caseClass: Expr, selector: Identifier) extends Expr with FixedType { val fixedType = classDef.fields.find(_.id == selector).get.getType } /* Arithmetic */ - case class Plus(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class Plus(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class Minus(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class Minus(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class UMinus(expr: Expr) extends Expr with FixedType { + @serializable case class UMinus(expr: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class Times(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class Times(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class Division(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class Division(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class LessThan(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class LessThan(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class GreaterThan(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class GreaterThan(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class LessEquals(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class LessEquals(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class GreaterEquals(lhs: Expr, rhs: Expr) extends Expr with FixedType { + @serializable case class GreaterEquals(lhs: Expr, rhs: Expr) extends Expr with FixedType { val fixedType = BooleanType } @@ -261,53 +261,53 @@ object Trees { // case class OptionNone(baseType: TypeTree) extends Expr with Terminal /* Set expressions */ - case class EmptySet(baseType: TypeTree) extends Expr with Terminal - case class FiniteSet(elements: Seq[Expr]) extends Expr - case class ElementOfSet(element: Expr, set: Expr) extends Expr with FixedType { + @serializable case class EmptySet(baseType: TypeTree) extends Expr with Terminal + @serializable case class FiniteSet(elements: Seq[Expr]) extends Expr + @serializable case class ElementOfSet(element: Expr, set: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class SetCardinality(set: Expr) extends Expr with FixedType { + @serializable case class SetCardinality(set: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class SubsetOf(set1: Expr, set2: Expr) extends Expr with FixedType { + @serializable case class SubsetOf(set1: Expr, set2: Expr) extends Expr with FixedType { val fixedType = BooleanType } - case class SetIntersection(set1: Expr, set2: Expr) extends Expr - case class SetUnion(set1: Expr, set2: Expr) extends Expr - case class SetDifference(set1: Expr, set2: Expr) extends Expr - case class SetMin(set: Expr) extends Expr - case class SetMax(set: Expr) extends Expr + @serializable case class SetIntersection(set1: Expr, set2: Expr) extends Expr + @serializable case class SetUnion(set1: Expr, set2: Expr) extends Expr + @serializable case class SetDifference(set1: Expr, set2: Expr) extends Expr + @serializable case class SetMin(set: Expr) extends Expr + @serializable case class SetMax(set: Expr) extends Expr /* Multiset expressions */ - case class EmptyMultiset(baseType: TypeTree) extends Expr with Terminal - case class FiniteMultiset(elements: Seq[Expr]) extends Expr - case class Multiplicity(element: Expr, multiset: Expr) extends Expr - case class MultisetCardinality(multiset: Expr) extends Expr with FixedType { + @serializable case class EmptyMultiset(baseType: TypeTree) extends Expr with Terminal + @serializable case class FiniteMultiset(elements: Seq[Expr]) extends Expr + @serializable case class Multiplicity(element: Expr, multiset: Expr) extends Expr + @serializable case class MultisetCardinality(multiset: Expr) extends Expr with FixedType { val fixedType = Int32Type } - case class SubmultisetOf(multiset1: Expr, multiset2: Expr) extends Expr - case class MultisetIntersection(multiset1: Expr, multiset2: Expr) extends Expr - case class MultisetUnion(multiset1: Expr, multiset2: Expr) extends Expr - case class MultisetPlus(multiset1: Expr, multiset2: Expr) extends Expr // disjoint union - case class MultisetDifference(multiset1: Expr, multiset2: Expr) extends Expr - case class MultisetToSet(multiset: Expr) extends Expr + @serializable case class SubmultisetOf(multiset1: Expr, multiset2: Expr) extends Expr + @serializable case class MultisetIntersection(multiset1: Expr, multiset2: Expr) extends Expr + @serializable case class MultisetUnion(multiset1: Expr, multiset2: Expr) extends Expr + @serializable case class MultisetPlus(multiset1: Expr, multiset2: Expr) extends Expr // disjoint union + @serializable case class MultisetDifference(multiset1: Expr, multiset2: Expr) extends Expr + @serializable case class MultisetToSet(multiset: Expr) extends Expr /* Map operations. */ - case class EmptyMap(fromType: TypeTree, toType: TypeTree) extends Expr with Terminal - case class SingletonMap(from: Expr, to: Expr) extends Expr - case class FiniteMap(singletons: Seq[SingletonMap]) extends Expr + @serializable case class EmptyMap(fromType: TypeTree, toType: TypeTree) extends Expr with Terminal + @serializable case class SingletonMap(from: Expr, to: Expr) extends Expr + @serializable case class FiniteMap(singletons: Seq[SingletonMap]) extends Expr - case class MapGet(map: Expr, key: Expr) extends Expr - case class MapUnion(map1: Expr, map2: Expr) extends Expr - case class MapDifference(map: Expr, keys: Expr) extends Expr + @serializable case class MapGet(map: Expr, key: Expr) extends Expr + @serializable case class MapUnion(map1: Expr, map2: Expr) extends Expr + @serializable case class MapDifference(map: Expr, keys: Expr) extends Expr /* List operations */ - case class NilList(baseType: TypeTree) extends Expr with Terminal - case class Cons(head: Expr, tail: Expr) extends Expr - case class Car(list: Expr) extends Expr - case class Cdr(list: Expr) extends Expr - case class Concat(list1: Expr, list2: Expr) extends Expr - case class ListAt(list: Expr, index: Expr) extends Expr + @serializable case class NilList(baseType: TypeTree) extends Expr with Terminal + @serializable case class Cons(head: Expr, tail: Expr) extends Expr + @serializable case class Car(list: Expr) extends Expr + @serializable case class Cdr(list: Expr) extends Expr + @serializable case class Concat(list1: Expr, list2: Expr) extends Expr + @serializable case class ListAt(list: Expr, index: Expr) extends Expr object UnaryOperator { def unapply(expr: Expr) : Option[(Expr,(Expr)=>Expr)] = expr match { @@ -732,8 +732,8 @@ object Trees { // Pulls out all let constructs to the top level, and makes sure they're // properly ordered. - private type DefPair = (Identifier,Expr) - private type DefPairs = List[DefPair] + @serializable private type DefPair = (Identifier,Expr) + @serializable private type DefPairs = List[DefPair] private def allLetDefinitions(expr: Expr) : DefPairs = treeCatamorphism[DefPairs]( (e: Expr) => Nil, (s1: DefPairs, s2: DefPairs) => s1 ::: s2, diff --git a/src/purescala/TypeTrees.scala b/src/purescala/TypeTrees.scala index da29f67f0ca7ddd79f17f3c6d6945cc3ff600cc3..6f65972d3343aac47fd55098cf928695d30b7b48 100644 --- a/src/purescala/TypeTrees.scala +++ b/src/purescala/TypeTrees.scala @@ -5,7 +5,7 @@ object TypeTrees { import Trees._ import Definitions._ - trait Typed { + @serializable trait Typed { self => private var _type: Option[TypeTree] = None @@ -22,7 +22,7 @@ object TypeTrees { } } - trait FixedType extends Typed { + @serializable trait FixedType extends Typed { self => val fixedType: TypeTree @@ -87,9 +87,9 @@ object TypeTrees { } // returns the number of distinct values that inhabit a type - sealed abstract class TypeSize - case class FiniteSize(size: Int) extends TypeSize - case object InfiniteSize extends TypeSize + @serializable sealed abstract class TypeSize + @serializable case class FiniteSize(size: Int) extends TypeSize + @serializable case object InfiniteSize extends TypeSize def domainSize(typeTree: TypeTree) : TypeSize = typeTree match { case Untyped => FiniteSize(0) @@ -122,25 +122,31 @@ object TypeTrees { case c: ClassType => InfiniteSize } - case object Untyped extends TypeTree - case object AnyType extends TypeTree - case object NoType extends TypeTree // This is the type of errors (ie. subtype of anything) - case object BooleanType extends TypeTree - case object Int32Type extends TypeTree + @serializable case object Untyped extends TypeTree + @serializable case object AnyType extends TypeTree + @serializable case object NoType extends TypeTree // This is the type of errors (ie. subtype of anything) + @serializable case object BooleanType extends TypeTree + @serializable case object Int32Type extends TypeTree - case class ListType(base: TypeTree) extends TypeTree - case class TupleType(bases: Seq[TypeTree]) extends TypeTree { lazy val dimension: Int = bases.length } - case class SetType(base: TypeTree) extends TypeTree - case class MultisetType(base: TypeTree) extends TypeTree - case class MapType(from: TypeTree, to: TypeTree) extends TypeTree - case class OptionType(base: TypeTree) extends TypeTree + @serializable case class ListType(base: TypeTree) extends TypeTree + @serializable case class TupleType(bases: Seq[TypeTree]) extends TypeTree { lazy val dimension: Int = bases.length } + @serializable case class SetType(base: TypeTree) extends TypeTree + @serializable case class MultisetType(base: TypeTree) extends TypeTree + @serializable case class MapType(from: TypeTree, to: TypeTree) extends TypeTree + @serializable case class OptionType(base: TypeTree) extends TypeTree @serializable sealed abstract class ClassType extends TypeTree { val classDef: ClassTypeDef val id: Identifier = classDef.id + + override def hashCode : Int = id.hashCode + override def equals(that : Any) : Boolean = that match { + case t : ClassType => t.id == this.id + case _ => false + } } - case class AbstractClassType(classDef: AbstractClassDef) extends ClassType - case class CaseClassType(classDef: CaseClassDef) extends ClassType + @serializable case class AbstractClassType(classDef: AbstractClassDef) extends ClassType + @serializable case class CaseClassType(classDef: CaseClassDef) extends ClassType def classDefToClassType(cd: ClassTypeDef): ClassType = cd match { case a: AbstractClassDef => AbstractClassType(a)