return false;
}
}
- if(isSet() && t.isSet()) {
- return getSetElementType().isSubtypeOf(t.getSetElementType());
- }
if (isFunction() && t.isFunction())
{
if (!isComparableTo(t))
if(isSubtypeOf(NodeManager::currentNM()->realType())) {
return t.isSubtypeOf(NodeManager::currentNM()->realType());
}
- if(isSet() && t.isSet()) {
- return getSetElementType().isComparableTo(t.getSetElementType());
- }
if (isFunction() && t.isFunction())
{
// comparable if they have a common type node
case kind::SEQUENCE_TYPE: return TypeNode();
case kind::SET_TYPE:
{
- // take the least common subtype of element types
- TypeNode elementType;
- if (t1.isSet()
- && !(elementType = commonTypeNode(t0[0], t1[0], isLeast)).isNull())
- {
- return NodeManager::currentNM()->mkSetType(elementType);
- }
- else
- {
- return TypeNode();
- }
+ // we don't support subtyping for sets
+ return TypeNode(); // return null type
}
- case kind::SEXPR_TYPE:
- Unimplemented()
- << "haven't implemented leastCommonType for symbolic expressions yet";
- default:
- Unimplemented() << "don't have a commonType for types `" << t0 << "' and `"
- << t1 << "'";
+ case kind::SEXPR_TYPE:
+ Unimplemented()
+ << "haven't implemented leastCommonType for symbolic expressions yet";
+ default:
+ Unimplemented() << "don't have a commonType for types `" << t0
+ << "' and `" << t1 << "'";
}
}
Trace("sets-mem") << std::endl;
}
}
- // check subtypes
- checkSubtypes();
d_im.doPendingLemmas();
if (d_im.hasSent())
{
<< std::endl;
}
-void TheorySetsPrivate::checkSubtypes()
-{
- Trace("sets") << "TheorySetsPrivate: check Subtypes..." << std::endl;
- const std::vector<Node>& sec = d_state.getSetsEqClasses();
- for (const Node& s : sec)
- {
- TypeNode mct = d_most_common_type[s];
- Assert(!mct.isNull());
- const std::map<Node, Node>& smems = d_state.getMembers(s);
- if (!smems.empty())
- {
- for (const std::pair<const Node, Node>& it2 : smems)
- {
- Trace("sets") << " check subtype " << it2.first << " " << it2.second
- << std::endl;
- Trace("sets") << " types : " << it2.first.getType() << " " << mct
- << std::endl;
- if (!it2.first.getType().isSubtypeOf(mct))
- {
- Node mctt = d_most_common_type_term[s];
- Assert(!mctt.isNull());
- Trace("sets") << " most common type term is " << mctt << std::endl;
- std::vector<Node> exp;
- exp.push_back(it2.second);
- Assert(d_state.areEqual(mctt, it2.second[1]));
- exp.push_back(mctt.eqNode(it2.second[1]));
- Node tc_k = d_treg.getTypeConstraintSkolem(it2.first, mct);
- if (!tc_k.isNull())
- {
- Node etc = tc_k.eqNode(it2.first);
- d_im.assertInference(etc, exp, "subtype-clash");
- if (d_state.isInConflict())
- {
- return;
- }
- }
- }
- }
- }
- }
- Trace("sets") << "TheorySetsPrivate: finished." << std::endl;
-}
-
void TheorySetsPrivate::checkDownwardsClosure()
{
Trace("sets") << "TheorySetsPrivate: check downwards closure..." << std::endl;
* Reset the information for a full effort check.
*/
void fullEffortReset();
- /**
- * This ensures that subtype constraints are met for all set terms. In
- * particular, for a set equivalence class E, let Set(T) be the most
- * common type among the types of terms in that class. In other words,
- * if E contains two terms of Set(Int) and Set(Real), then Set(Int) is the
- * most common type. Then, for each membership x in S where S is a set in
- * this equivalence class, we ensure x has type T by asserting:
- * x = k
- * for a fresh constant k of type T. This is done only if the type of x is not
- * a subtype of Int (e.g. if x is of type Real). We call k the "type
- * constraint skolem for x of type Int".
- */
- void checkSubtypes();
/**
* This implements an inference schema based on the "downwards closure" of
* set membership. This roughly corresponds to the rules UNION DOWN I and II,
}
};/* struct SetSubsetTypeRule */
-struct MemberTypeRule {
- inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+struct MemberTypeRule
+{
+ inline static TypeNode computeType(NodeManager* nodeManager,
+ TNode n,
+ bool check)
{
Assert(n.getKind() == kind::MEMBER);
TypeNode setType = n[1].getType(check);
- if( check ) {
- if(!setType.isSet()) {
- throw TypeCheckingExceptionPrivate(n, "checking for membership in a non-set");
+ if (check)
+ {
+ if (!setType.isSet())
+ {
+ throw TypeCheckingExceptionPrivate(
+ n, "checking for membership in a non-set");
}
TypeNode elementType = n[0].getType(check);
- // TODO : still need to be flexible here due to situations like:
- //
- // T : (Set Int)
- // S : (Set Real)
- // (= (as T (Set Real)) S)
- // (member 0.5 S)
- // ...where (member 0.5 T) is inferred
- //
- // or
- //
- // S : (Set Real)
- // (not (member 0.5 s))
- // (member 0.0 s)
- // ...find model M where M( s ) = { 0 }, check model will generate (not (member 0.5 (singleton 0)))
- //
- if(!elementType.isComparableTo(setType.getSetElementType())) {
- //if(!elementType.isSubtypeOf(setType.getSetElementType())) { //FIXME:typing
+ // e.g. (member 1 (singleton 1.0)) is true whereas
+ // (member 1.0 (singleton 1)) throws a typing error
+ if (!elementType.isSubtypeOf(setType.getSetElementType()))
+ {
std::stringstream ss;
ss << "member operating on sets of different types:\n"
<< "child type: " << elementType << "\n"
}
return nodeManager->booleanType();
}
-};/* struct MemberTypeRule */
+}; /* struct MemberTypeRule */
struct SingletonTypeRule
{
; COMMAND-LINE: --sets-ext
-; EXPECT: unsat
+; EXPECT: sat
(set-logic ALL)
-(set-info :status unsat)
+(set-info :status sat)
(declare-fun a () (Set Real))
(declare-fun x () Real)
-(assert (= (as univset (Set Real)) (as univset (Set Int))))
+(assert (= (as univset (Set Real)) (as univset (Set Real))))
(assert (member x a))
(declare-fun x () Real)
-(assert (= (as univset (Set Real)) (as univset (Set Int))))
+(assert (= (as univset (Set Real)) (as univset (Set Real))))
(assert (member x a))
(set-logic QF_LIRAFS)
-(set-info :status unsat)
+(set-info :status sat)
(declare-fun s () (Set (Set Real)))
-(declare-fun t () (Set (Set Int)))
+(declare-fun t () (Set (Set Real)))
-(declare-fun x () (Set Int))
+(declare-fun x () (Set Real))
(declare-fun y () (Set Real))
(assert (member 0.5 y))
(set-logic QF_UFLIRAFS)
-(set-info :status unsat)
-(declare-fun s () (Set Int))
+(set-info :status sat)
+(declare-fun s () (Set Real))
(declare-fun t () (Set Real))
(declare-fun r () (Set Real))
(declare-fun u () (Set Real))
setSortI = solver.mkSetSort(intSort)
setSortR = solver.mkSetSort(realSort)
- # we support subtyping for sets
- assert setSortI.isSubsortOf(setSortR)
- assert setSortR.isComparableTo(setSortI)
+ # we don't support subtyping for sets
+ assert not setSortI.isComparableTo(setSortR)
+ assert not setSortI.isSubsortOf(setSortR)
+ assert not setSortR.isComparableTo(setSortI)
+ assert not setSortR.isSubsortOf(setSortI)
+
Sort setSortI = d_solver.mkSetSort(intSort);
Sort setSortR = d_solver.mkSetSort(realSort);
- // we support subtyping for sets
- TS_ASSERT(setSortI.isSubsortOf(setSortR));
- TS_ASSERT(setSortR.isComparableTo(setSortI));
+ // we don't support subtyping for sets
+ TS_ASSERT(!setSortI.isComparableTo(setSortR));
+ TS_ASSERT(!setSortI.isSubsortOf(setSortR));
+ TS_ASSERT(!setSortR.isComparableTo(setSortI));
+ TS_ASSERT(!setSortR.isSubsortOf(setSortI));
}
d_em.reset();
}
+ void testIsisComparableTo()
+ {
+ TypeNode setRealType = d_nm->mkSetType(d_nm->realType());
+ TypeNode setIntType = d_nm->mkSetType(d_nm->integerType());
+ TS_ASSERT(!setIntType.isComparableTo(setRealType));
+ TS_ASSERT(!setIntType.isSubtypeOf(setRealType));
+ TS_ASSERT(!setRealType.isComparableTo(setIntType));
+ TS_ASSERT(!setRealType.isComparableTo(setIntType));
+ }
+
void testSingletonTerm()
{
Sort realSort = d_slv->getRealSort();