Remove subtyping for sets (#5205)
authormudathirmahgoub <mudathirmahgoub@gmail.com>
Tue, 6 Oct 2020 00:49:32 +0000 (19:49 -0500)
committerGitHub <noreply@github.com>
Tue, 6 Oct 2020 00:49:32 +0000 (19:49 -0500)
Removed subtyping for sets in type_node.h

Fixes #4502, fixes #4631.

src/expr/type_node.cpp
src/theory/sets/theory_sets_private.cpp
src/theory/sets/theory_sets_private.h
src/theory/sets/theory_sets_type_rules.h
test/regress/regress0/sets/int-real-univ-unsat.smt2
test/regress/regress0/sets/int-real-univ.smt2
test/regress/regress0/sets/sets-of-sets-subtypes.smt2
test/regress/regress0/sets/sets-poly-nonint.smt2
test/unit/api/python/test_sort.py
test/unit/api/sort_black.h
test/unit/theory/theory_sets_type_rules_white.h

index cbfb57747ee28f19039d878e4192510c96c25b56..659b1eef22da2ea2452bd139b52f44693643a91f 100644 (file)
@@ -318,9 +318,6 @@ bool TypeNode::isSubtypeOf(TypeNode t) const {
       return false;
     }
   }
-  if(isSet() && t.isSet()) {
-    return getSetElementType().isSubtypeOf(t.getSetElementType());
-  }
   if (isFunction() && t.isFunction())
   {
     if (!isComparableTo(t))
@@ -342,9 +339,6 @@ bool TypeNode::isComparableTo(TypeNode t) const {
   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
@@ -583,24 +577,15 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) {
     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 << "'";
   }
 }
 
index 18df43e9f196b1bdbe5d9600476f11482d3ed3a1..db2f3f22f05160ab925dc0edd16f831e657fa5e1 100644 (file)
@@ -361,8 +361,6 @@ void TheorySetsPrivate::fullEffortCheck()
         Trace("sets-mem") << std::endl;
       }
     }
-    // check subtypes
-    checkSubtypes();
     d_im.doPendingLemmas();
     if (d_im.hasSent())
     {
@@ -418,49 +416,6 @@ void TheorySetsPrivate::fullEffortCheck()
                 << 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;
index 5ac40515a432bf0df910a752ba6f9804d6c55ed7..8247d49404afe2591f111d921ab66d80a81dd10a 100644 (file)
@@ -61,19 +61,6 @@ class TheorySetsPrivate {
    * 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,
index 20e5e57e21d26e7a4dc93f957577a0659e70cced..c5e86f10cc95359d9b6c8340e9237ed6a90e0747 100644 (file)
@@ -84,33 +84,26 @@ struct SubsetTypeRule {
   }
 };/* 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"
@@ -121,7 +114,7 @@ struct MemberTypeRule {
     }
     return nodeManager->booleanType();
   }
-};/* struct MemberTypeRule */
+}; /* struct MemberTypeRule */
 
 struct SingletonTypeRule
 {
index 56f7e8c5e6bda2385a38cfa8857c43afc74ea887..19b5850fa99057c102c4c37be71128d2ee823ea6 100644 (file)
@@ -1,13 +1,13 @@
 ; 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))
 
index afe20b92fa2fcb016dd0adfd63f4817835295170..e7d79bbf64bd2272f059ef3fc1e904e9029ea8fe 100644 (file)
@@ -7,7 +7,7 @@
 
 (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))
 
index 86a1d93b4b0ab300522ae0690961dd321f25e19c..e8c98e09c9843ab437a18f58df76ec91fa9d31fe 100644 (file)
@@ -1,10 +1,10 @@
 (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))
index a0e883ace00f831577f02083e95366bb35c9c788..58ff563bc6365500904493c0420ac0467555c61e 100644 (file)
@@ -1,6 +1,6 @@
 (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))
index 12fec6c91b706d00adb536907230914c9caa479e..cff92ca8d027411022b08a234cec028d7d12eac0 100644 (file)
@@ -347,6 +347,9 @@ def testSortSubtyping():
 
     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)
+
index 32108bf84acee774c4baa60577137e2844aef32a..53563f8333fdab057b4c55ad0893f665b9e02af0 100644 (file)
@@ -372,7 +372,9 @@ void SortBlack::testSortSubtyping()
 
   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));
 }
index 06f5608c87c064f2dda61889610e8661ee5249d8..c098ca9b8a4241a82f95d8427a1e32ffe3fb473b 100644 (file)
@@ -41,6 +41,16 @@ class SetsTypeRuleWhite : public CxxTest::TestSuite
     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();