@@ -903,74 +903,92 @@ trait SymbolOps { self: TypeOps =>
903
903
defs.foldRight(bd){ case ((vd, e), body) => Let (vd, e, body) }
904
904
}
905
905
906
- def hasInstance (tpe : Type ): Option [Boolean ] = tpe match {
906
+ protected def hasInstance (tpe : Type , seen : Set [ Type ] ): Option [Boolean ] = tpe match {
907
907
case _ : TypeParameter => None
908
- case MapType (_, to) => hasInstance(to)
909
- case TupleType (tpes) => if (tpes.forall(tp => hasInstance(tp) contains true )) Some (true ) else None
908
+ case MapType (_, to) => hasInstance(to, seen )
909
+ case TupleType (tpes) => if (tpes.forall(tp => hasInstance(tp, seen ) contains true )) Some (true ) else None
910
910
case SigmaType (params, to) =>
911
- if ((params.map(_.tpe) :+ to).forall(tp => hasInstance(tp) contains true )) Some (true ) else None
911
+ if ((params.map(_.tpe) :+ to).forall(tp => hasInstance(tp, seen ) contains true )) Some (true ) else None
912
912
case adt : ADTType =>
913
913
val sort = adt.getSort
914
- if (sort.hasInvariant) None
914
+ if (seen(adt)) None
915
+ else if (sort.hasInvariant) None
915
916
else if (! sort.definition.isWellFormed) Some (false )
916
- else Some (true )
917
+ else if (sort.constructors.sortBy(_.fields.size).exists(cons =>
918
+ cons.fields.forall(vd => hasInstance(vd.tpe, seen + adt) contains true )))
919
+ Some (true )
920
+ else None
917
921
case _ : RefinementType => None
918
922
case _ => Some (true )
919
923
}
920
924
925
+ final def hasInstance (tpe : Type ): Option [Boolean ] = hasInstance(tpe, Set ())
926
+
921
927
case class NoSimpleValue (tpe : Type ) extends Exception (s " No simple value found for type $tpe" )
922
928
923
929
/** Returns simplest value of a given type */
924
- def simplestValue (tpe : Type , allowSolver : Boolean = true )(implicit sem : symbols.Semantics , ctx : Context ): Expr = {
925
- def rec (tpe : Type , seen : Set [Type ]): Expr = tpe match {
926
- case StringType () => StringLiteral (" " )
927
- case BVType (signed, size) => BVLiteral (signed, 0 , size)
928
- case RealType () => FractionLiteral (0 , 1 )
929
- case IntegerType () => IntegerLiteral (0 )
930
- case CharType () => CharLiteral ('a' )
931
- case BooleanType () => BooleanLiteral (false )
932
- case UnitType () => UnitLiteral ()
933
- case SetType (baseType) => FiniteSet (Seq (), baseType)
934
- case BagType (baseType) => FiniteBag (Seq (), baseType)
935
- case MapType (fromType, toType) => FiniteMap (Seq (), rec(toType, seen), fromType, toType)
936
- case TupleType (tpes) => Tuple (tpes.map(rec(_, seen)))
937
-
938
- case adt @ ADTType (id, tps) =>
939
- val sort = adt.getSort
940
- if (! sort.definition.isWellFormed) throw NoSimpleValue (adt)
941
-
942
- if (seen(adt)) {
943
- Choose (ValDef .fresh(" res" , adt), BooleanLiteral (true ))
944
- } else if (sort.hasInvariant) {
945
- if (! allowSolver) throw NoSimpleValue (adt)
946
-
947
- val p = Variable .fresh(" p" , FunctionType (Seq (adt), BooleanType ()))
948
- val res = Variable .fresh(" v" , adt)
949
-
950
- import solvers ._
951
- import SolverResponses ._
952
-
953
- SimpleSolverAPI (sem.getSolver).solveSAT(Application (p, Seq (res))) match {
954
- case SatWithModel (model) => model.vars.get(res.toVal).getOrElse(throw NoSimpleValue (adt))
955
- case _ => throw NoSimpleValue (adt)
930
+ protected def simplestValue (tpe : Type , seen : Set [Type ], allowSolver : Boolean , inLambda : Boolean )
931
+ (implicit sem : symbols.Semantics , ctx : Context ): Expr = tpe match {
932
+ case StringType () => StringLiteral (" " )
933
+ case BVType (signed, size) => BVLiteral (signed, 0 , size)
934
+ case RealType () => FractionLiteral (0 , 1 )
935
+ case IntegerType () => IntegerLiteral (0 )
936
+ case CharType () => CharLiteral ('a' )
937
+ case BooleanType () => BooleanLiteral (false )
938
+ case UnitType () => UnitLiteral ()
939
+ case SetType (baseType) => FiniteSet (Seq (), baseType)
940
+ case BagType (baseType) => FiniteBag (Seq (), baseType)
941
+ case MapType (fromType, toType) => FiniteMap (Seq (), simplestValue(toType, seen, allowSolver, inLambda), fromType, toType)
942
+ case TupleType (tpes) => Tuple (tpes.map(simplestValue(_, seen, allowSolver, inLambda)))
943
+
944
+ case adt @ ADTType (id, tps) =>
945
+ val sort = adt.getSort
946
+ if (! sort.definition.isWellFormed) throw NoSimpleValue (adt)
947
+
948
+ if (seen(adt)) {
949
+ if (inLambda) Choose (ValDef .fresh(" res" , adt), BooleanLiteral (true ))
950
+ else throw NoSimpleValue (adt)
951
+ } else if (sort.hasInvariant) {
952
+ if (! allowSolver) throw NoSimpleValue (adt)
953
+
954
+ val p = Variable .fresh(" p" , FunctionType (Seq (adt), BooleanType ()))
955
+ val res = Variable .fresh(" v" , adt)
956
+
957
+ import solvers ._
958
+ import SolverResponses ._
959
+
960
+ SimpleSolverAPI (sem.getSolver).solveSAT(Application (p, Seq (res))) match {
961
+ case SatWithModel (model) => model.vars.get(res.toVal).getOrElse(throw NoSimpleValue (adt))
962
+ case _ => throw NoSimpleValue (adt)
963
+ }
964
+ } else {
965
+ for (cons <- sort.constructors.sortBy(_.fields.size)) {
966
+ try {
967
+ return ADT (
968
+ cons.id,
969
+ cons.tps,
970
+ cons.fields.map(vd => simplestValue(vd.getType, seen + adt, allowSolver, inLambda))
971
+ )
972
+ } catch {
973
+ case NoSimpleValue (_) => ()
956
974
}
957
- } else {
958
- val cons = sort.constructors.sortBy(_.fields.size).head
959
- ADT (cons.id, cons.tps, cons.fields.map(vd => rec(vd.getType, seen + adt)))
960
975
}
976
+ throw NoSimpleValue (adt)
977
+ }
961
978
962
- case tp : TypeParameter =>
963
- GenericValue (tp, 0 )
964
-
965
- case ft @ FunctionType (from, to) =>
966
- Lambda (from.map(tpe => ValDef .fresh(" x" , tpe, true )), rec(to, seen))
979
+ case tp : TypeParameter =>
980
+ GenericValue (tp, 0 )
967
981
968
- case _ => throw NoSimpleValue (tpe)
969
- }
982
+ case ft @ FunctionType (from, to) =>
983
+ Lambda (from.map(tpe => ValDef .fresh( " x " , tpe, true )), simplestValue(to, seen, allowSolver, true ))
970
984
971
- rec (tpe, Set .empty )
985
+ case _ => throw NoSimpleValue (tpe)
972
986
}
973
987
988
+ final def simplestValue (tpe : Type , allowSolver : Boolean = true )
989
+ (implicit sem : symbols.Semantics , ctx : Context ): Expr = {
990
+ simplestValue(tpe, Set .empty, allowSolver, false )
991
+ }
974
992
975
993
/** Hoists all IfExpr at top level.
976
994
*
0 commit comments