addOperator(kind::SUBSET, "subset");
addOperator(kind::MEMBER, "member");
addOperator(kind::SINGLETON, "singleton");
+ addOperator(kind::INSERT, "insert");
break;
case THEORY_DATATYPES:
case kind::MEMBER: return "member";
case kind::SET_TYPE: return "Set";
case kind::SINGLETON: return "singleton";
+ case kind::INSERT: return "insert";
default:
; /* fall through */
}
operator SUBSET 2 "subset predicate; first parameter a subset of second"
operator MEMBER 2 "set membership predicate; first parameter a member of second"
operator SINGLETON 1 "the set of the single element given as a parameter"
+operator INSERT 2: "set obtained by inserting elements (first N-1 parameters) into a set (the last parameter)"
typerule UNION ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
typerule INTERSECTION ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
typerule MEMBER ::CVC4::theory::sets::MemberTypeRule
typerule SINGLETON ::CVC4::theory::sets::SingletonTypeRule
typerule EMPTYSET ::CVC4::theory::sets::EmptySetTypeRule
+typerule INSERT ::CVC4::theory::sets::InsertTypeRule
construle UNION ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
construle INTERSECTION ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
construle SETMINUS ::CVC4::theory::sets::SetsBinaryOperatorTypeRule
construle SINGLETON ::CVC4::theory::sets::SingletonTypeRule
+construle INSERT ::CVC4::theory::sets::InsertTypeRule
endtheory
return RewriteResponse(REWRITE_DONE, nm->mkConst(true));
// Further optimization, if constants but differing ones
+ if(node.getKind() == kind::INSERT) {
+ Node insertedElements = nm->mkNode(kind::SINGLETON, node[0]);
+ size_t setNodeIndex = node.getNumChildren()-1;
+ for(size_t i = 1; i < setNodeIndex; ++i) {
+ insertedElements = nm->mkNode(kind::UNION, insertedElements, nm->mkNode(kind::SINGLETON, node[i]));
+ }
+ return RewriteResponse(REWRITE_AGAIN, nm->mkNode(kind::UNION, insertedElements, node[setNodeIndex]));
+ }//kind::INSERT
+
if(node.getType().isSet() && node.isConst()) {
//rewrite set to normal form
SettermElementsMap setTermElementsMap; // cache
}
};/* struct EmptySetTypeRule */
+struct InsertTypeRule {
+ inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+ throw (TypeCheckingExceptionPrivate, AssertionException) {
+ Assert(n.getKind() == kind::INSERT);
+ size_t numChildren = n.getNumChildren();
+ Assert( numChildren >= 2 );
+ TypeNode setType = n[numChildren-1].getType(check);
+ if( check ) {
+ if(!setType.isSet()) {
+ throw TypeCheckingExceptionPrivate(n, "inserting into a non-set");
+ }
+ for(size_t i = 0; i < numChildren-1; ++i) {
+ TypeNode elementType = n[i].getType(check);
+ if(elementType != setType.getSetElementType()) {
+ throw TypeCheckingExceptionPrivate
+ (n, "type of element should be same as element type of set being inserted into");
+ }
+ }
+ }
+ return setType;
+ }
+
+ inline static bool computeIsConst(NodeManager* nodeManager, TNode n) {
+ Assert(n.getKind() == kind::INSERT);
+ return n[0].isConst() && n[1].isConst();
+ }
+};/* struct InsertTypeRule */
+
struct SetsProperties {
inline static Cardinality computeCardinality(TypeNode type) {
error1.smt2 \
error2.smt2 \
eqtest.smt2 \
+ insert.smt2 \
fuzz14418.smt2 \
fuzz15201.smt2 \
fuzz31811.smt2 \
--- /dev/null
+(set-option :produce-models true)
+(set-logic QF_UFLIA_SETS)
+(set-info :status sat)
+(declare-fun X () (Set Int))
+(assert (= X (insert 1 2 (singleton 3))))
+(check-sat)
+;(get-model)