docs: Migrate sets and relations theory reference. (#6698)
authorAina Niemetz <aina.niemetz@gmail.com>
Wed, 9 Jun 2021 20:44:13 +0000 (13:44 -0700)
committerGitHub <noreply@github.com>
Wed, 9 Jun 2021 20:44:13 +0000 (20:44 +0000)
This migrates page https://cvc4.github.io/sets-and-relations.
It further adds the SMT2 version of examples/api/cpp/sets.cpp and adds
test/regress/regress0/rels/relations-ops.smt2 as smtlib example for
relations.

docs/examples/examples.rst
docs/examples/relations.rst [new file with mode: 0644]
docs/examples/sets.rst
docs/ext/examples.py
docs/ext/smtliblexer.py
docs/theories/datatypes.rst
docs/theories/sets-and-relations.rst [new file with mode: 0644]
docs/theory.rst
examples/api/cpp/sets.cpp
examples/api/smtlib/relations.smt2 [new file with mode: 0644]
examples/api/smtlib/sets.smt2 [new file with mode: 0644]

index 528566a3e8d67d06d98b6dd0bd9e8bba75de5e16..5e17d524b01eb076d948accc132abe4d5d951df4 100644 (file)
@@ -16,10 +16,11 @@ For every example, the same problem is constructed and solved using different in
     datatypes
     floatingpoint
     lineararith
+    relations
     sequences
     sets
     strings
     combination
     sygus-fun
     sygus-grammar
-    sygus-inv
\ No newline at end of file
+    sygus-inv
diff --git a/docs/examples/relations.rst b/docs/examples/relations.rst
new file mode 100644 (file)
index 0000000..d94fa0a
--- /dev/null
@@ -0,0 +1,7 @@
+Theory of Relations
+===================
+
+
+.. api-examples::
+    ../../examples/api/smtlib/relations.smt2
+
index 71a6843c336f707479bca48b0e050561fdfe48e6..b0f1fc1dacc043fca0e54368887a4fa20850bdd0 100644 (file)
@@ -5,3 +5,4 @@ Theory of Sets
 .. api-examples::
     ../../examples/api/cpp/sets.cpp
     ../../examples/api/python/sets.py
+    ../../examples/api/smtlib/sets.smt2
index 003726de4a61e393ecb581a4bee818db699e77e9..9f8f7294edcce1e96c11ac882c95941e1b13565f 100644 (file)
@@ -22,7 +22,7 @@ class APIExamples(Directive):
         '.cpp': {'title': 'C++', 'lang': 'c++'},
         '.java': {'title': 'Java', 'lang': 'java'},
         '.py': {'title': 'Python', 'lang': 'python'},
-        '.smt2': {'title': 'SMT-LIBv2', 'lang': 'lisp'},
+        '.smt2': {'title': 'SMT-LIBv2', 'lang': 'smtlib'},
     }
 
     # The "arguments" are actually the content of the directive
index 2ce860e395ac18d61836bad37f2025253179d855..e796e2404556910a2f6460173569e763d14bd8a7 100644 (file)
@@ -7,10 +7,11 @@ class SmtLibLexer(RegexLexer):
 
     tokens = {
         'root': [
-            (r'QF_BV', token.Text),
-            (r'QF_UFDT', token.Text),
             (r'ALL', token.Text),
             (r'QF_ALL', token.Text),
+            (r'QF_BV', token.Text),
+            (r'QF_UFDT', token.Text),
+            (r'QF_UFLIAFS', token.Text),
             (r'set-info', token.Keyword),
             (r'set-logic', token.Keyword),
             (r'set-option', token.Keyword),
@@ -38,13 +39,19 @@ class SmtLibLexer(RegexLexer):
             (r':produce-unsat-assumptions', token.Name.Attribute),
             (r':status', token.Name.Attribute),
             (r'!', token.Name.Attribute),
+            (r'Array', token.Name.Attribute),
             (r'BitVec', token.Name.Attribute),
+            (r'Int', token.Name.Attribute),
             (r'RNE', token.Name.Attribute),
+            (r'Set', token.Name.Attribute),
+            (r'String', token.Name.Attribute),
             (r'Tuple', token.Name.Attribute),
+            (r'tupSel', token.Name.Attribute),
             (r'true', token.String),
             (r'distinct', token.Operator),
             (r'=', token.Operator),
             (r'>', token.Operator),
+            (r'\*', token.Operator),
             (r'and', token.Operator),
             (r'bvadd', token.Operator),
             (r'bvashr', token.Operator),
@@ -53,14 +60,29 @@ class SmtLibLexer(RegexLexer):
             (r'bvult', token.Operator),
             (r'bvule', token.Operator),
             (r'bvsdiv', token.Operator),
+            (r'card', token.Operator),
             (r'emp', token.Operator),
+            (r'emptyset', token.Operator),
+            (r'exists', token.Operator),
             (r'extract', token.Operator),
+            (r'forall', token.Operator),
             (r'fp.gt', token.Operator),
+            (r'insert', token.Operator),
+            (r'intersection', token.Operator),
             (r'ite', token.Operator),
+            (r'member', token.Operator),
             (r'mkTuple', token.Operator),
-            (r'to_fp_unsigned', token.Operator),
+            (r'not', token.Operator),
+            (r'product', token.Operator),
             (r'pto', token.Operator),
             (r'sep', token.Operator),
+            (r'singleton', token.Operator),
+            (r'subset', token.Operator),
+            (r'tclosure', token.Operator),
+            (r'to_fp_unsigned', token.Operator),
+            (r'transpose', token.Operator),
+            (r'union', token.Operator),
+            (r'univset', token.Operator),
             (r'wand', token.Operator),
             (r'\+zero', token.Operator),
             (r'#b[0-1]+', token.Text),
@@ -76,5 +98,3 @@ class SmtLibLexer(RegexLexer):
             (r'\.\.\.', token.Text)
         ]
     }
-
-
index 7dd0e8713a0cec347ac5230b33c9f425f512497b..5f02a8bf84bd62aafb6b838f395f891c12cc4afd 100644 (file)
@@ -179,7 +179,7 @@ a `cvc5::api::Solver solver` object.
 |                    |                                        |                                                                                                                                 |
 |                    |                                        | ``Sort s = solver.mkTupleSort(sorts);``                                                                                         |
 +--------------------+----------------------------------------+---------------------------------------------------------------------------------------------------------------------------------+
-|                    | ``(declare-const t (tuple Int Int))``  | ``Sort s_int = solver.getIntegerSort();``                                                                                       |
+|                    | ``(declare-const t (Tuple Int Int))``  | ``Sort s_int = solver.getIntegerSort();``                                                                                       |
 |                    |                                        |                                                                                                                                 |
 |                    |                                        | ``Sort s = solver.mkTypleSort({s_int, s_int});``                                                                                |
 |                    |                                        |                                                                                                                                 |
diff --git a/docs/theories/sets-and-relations.rst b/docs/theories/sets-and-relations.rst
new file mode 100644 (file)
index 0000000..7983833
--- /dev/null
@@ -0,0 +1,201 @@
+Theory Reference: Sets and Relations
+====================================
+
+Finite Sets
+-----------
+
+cvc5 supports the theory of finite sets.
+The simplest way to get a sense of the syntax is to look at an example:
+
+.. api-examples::
+    ../../examples/api/cpp/sets.cpp
+    ../../examples/api/python/sets.py
+    ../../examples/api/smtlib/sets.smt2
+
+The source code of these examples is available at:
+
+* `SMT-LIB 2 language example <https://github.com/cvc5/cvc5/blob/master/examples/api/smtlib/sets.smt2>`__
+* `C++ API example <https://github.com/cvc5/cvc5/blob/master/examples/api/cpp/sets.cpp>`__
+* `Python API example <https://github.com/cvc5/cvc5/blob/master/examples/api/python/sets.cpp>`__
+
+
+Below is a short summary of the sorts, constants, functions and
+predicates.  For more details, see
+`this paper at IJCAR 2016 <https://cvc4.github.io/publications/2016/BRBT16.pdf>`__.
+
+For the C++ API examples in the table below, we assume that we have created
+a `cvc5::api::Solver solver` object.
+
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+|                      | SMTLIB language                              | C++ API                                                            |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Logic String         | append `FS` for finite sets                  | append `FS` for finite sets                                        |
+|                      |                                              |                                                                    |
+|                      | ``(set-logic QF_UFLIAFS)``                   | ``solver.setLogic("QF_UFLIAFS");``                                 |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Sort                 | ``(Set <Sort>)``                             | ``solver.mkSetSort(cvc5::api::Sort elementSort);``                 |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Constants            | ``(declare-const X (Set Int)``               | ``Sort s = solver.mkSetSort(solver.getIntegerSort());``            |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term X = solver.mkConst(s, "X");``                               |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Union                | ``(union X Y)``                              | ``Term Y = solver.mkConst(s, "Y");``                               |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term t = solver.mkTerm(Kind::UNION, X, Y);``                     |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Intersection         | ``(setminus X Y)``                           | ``Term t = solver.mkTerm(Kind::SETMINUS, X, Y);``                  |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Membership           | ``(member x X)``                             | ``Term x = solver.mkConst(solver.getIntegerSort(), "x");``         |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term t = solver.mkTerm(Kind::MEMBER, x, X);``                    |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Subset               | ``(subset X Y)``                             | ``Term t = solver.mkTerm(Kind::SUBSET, X, Y);``                    |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Emptyset             | ``(as emptyset (Set Int)``                   | ``Term t = solver.mkEmptySet(s);``                                 |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Singleton Set        | ``(singleton 1)``                            | ``Term t = solver.mkTerm(Kind::SINGLETON, solver.mkInteger(1));``  |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Cardinality          | ``(card X)``                                 | ``Term t = solver.mkTerm(Kind::CARD, X);``                         |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Insert / Finite Sets | ``(insert 1 2 3 (singleton 4))``             | ``Term one = solver.mkInteger(1);``                                |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term two = solver.mkInteger(2);``                                |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term three = solver.mkInteger(3);``                              |
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term sgl = solver.mkTerm(Kind::SINGLETON, solver.mkInteger(4));``|
+|                      |                                              |                                                                    |
+|                      |                                              | ``Term t = solver.mkTerm(Kind::INSERT, {one, two, three, sgl});``  |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Complement           | ``(complement X)``                           | ``Term t = solver.mkTerm(Kind::COMPLEMENT, X);``                   |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+| Universe Set         | ``(as univset (Set Int))``                   | ``Term t = solver.mkUniverseSet(s);``                              |
++----------------------+----------------------------------------------+--------------------------------------------------------------------+
+
+
+Semantics
+^^^^^^^^^
+
+The semantics of most of the above operators (e.g., set union, intersection,
+difference) are straightforward.
+The semantics for the universe set and complement are more subtle and explained
+in the following.
+
+The universe set ``(as univset (Set T))`` is *not* interpreted as the set
+containing all elements of sort ``T``.
+Instead it may be interpreted as any set such that all sets of sort ``(Set T)``
+are interpreted as subsets of it.
+In other words, it is the union of the interpretations of all (finite) sets in
+our input.
+
+For example:
+
+.. code:: smtlib
+
+  (declare-fun x () (Set Int))
+  (declare-fun y () (Set Int))
+  (declare-fun z () (Set Int))
+  (assert (member 0 x))
+  (assert (member 1 y))
+  (assert (= z (as univset (Set Int))))
+  (check-sat)
+
+Here, a possible model is:
+
+.. code:: smtlib
+
+  (define-fun x () (singleton 0))
+  (define-fun y () (singleton 1))
+  (define-fun z () (union (singleton 1) (singleton 0)))
+
+Notice that the universe set in this example is interpreted the same as ``z``,
+and is such that all sets in this example (``x``, ``y``, and ``z``) are subsets
+of it.
+
+The set complement operator for ``(Set T)`` is interpreted relative to the
+interpretation of the universe set for ``(Set T)``, and not relative to the set
+of all elements of sort ``T``.
+That is, for all sets ``X`` of sort ``(Set T)``, the complement operator is
+such that ``(= (complement X) (setminus (as univset (Set T)) X))``
+holds in all models.
+
+The motivation for these semantics is to ensure that the universe set for sort
+``T`` and applications of set complement can always be interpreted as a finite
+set in (quantifier-free) inputs, even if the cardinality of ``T`` is infinite. 
+Above, notice that we were able to find a model for the universe set of sort 
+``(Set Int)`` that contained two elements only.
+
+.. note::
+  In the presence of quantifiers, cvc5's implementation of the above theory
+  allows infinite sets.
+  In particular, the following formula is SAT (even though cvc5 is not able to
+  say this):
+
+  .. code:: smtlib
+
+    (set-logic ALL)
+    (declare-fun x () (Set Int))
+    (assert (forall ((z Int) (member (* 2 z) x)))
+    (check-sat)
+
+  The reason for that is that making this formula (and similar ones) `unsat` is
+  counter-intuitive when quantifiers are present.
+
+Finite Relations
+----------------
+
+Example:
+
+.. api-examples::
+    ../../examples/api/smtlib/relations.smt2
+
+For reference, below is a short summary of the sorts, constants, functions and
+predicates.
+For more details, see
+`this paper at CADE 2017 <https://cvc4.github.io/publications/2017/MRT+17.pdf>`__.
+
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+|                      | SMTLIB language                              | C++ API                                                                            |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Logic String         | ``(set-logic QF_ALL)``                       | ``solver.setLogic("QF_ALL");``                                                     |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Tuple Sort           | ``(Tuple <Sort_1>, ..., <Sort_n>)``          | ``std::vector<cvc5::api::Sort> sorts = { ... };``                                  |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Sort s = solver.mkTupleSort(sorts);``                                            |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+|                      | ``(declare-const t (Tuple Int Int))``        | ``Sort s_int = solver.getIntegerSort();``                                          |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Sort s = solver.mkTypleSort({s_int, s_int});``                                   |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term t = solver.mkConst(s, "t");``                                               |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Tuple Constructor    | ``(mkTuple <Term_1>, ..., <Term_n>)``        | ``Sort s = solver.mkTypleSort(sorts);``                                            |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Datatype dt = s.getDatatype();``                                                 |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term c = dt[0].getConstructor();``                                               |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term t = solver.mkTerm(Kind::APPLY_CONSTRUCTOR, {c, <Term_1>, ..., <Term_n>});`` |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Tuple Selector       | ``((_ tupSel i) t)``                         | ``Sort s = solver.mkTypleSort(sorts);``                                            |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Datatype dt = s.getDatatype();``                                                 |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term c = dt[0].getSelector();``                                                  |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term t = solver.mkTerm(Kind::APPLY_SELECTOR, {s, t});``                          |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Reation Sort         | ``(Set (Tuple <Sort_1>, ..., <Sort_n>))``    | ``Sort s = solver.mkSetSort(cvc5::api::Sort tupleSort);``                          |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Constants            | ``(declare-const X (Set (Tuple Int Int)``    | ``Sort s = solver.mkSetSort(solver.mkTupleSort({s_int, s_int});``                  |
+|                      |                                              |                                                                                    |
+|                      |                                              | ``Term X = solver.mkConst(s, "X");``                                               |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Transpose            | ``(transpose X)``                            | ``Term t = solver.mkTerm(Kind::TRANSPOSE, X);``                                    |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Transitive Closure   | ``(tclosure X)``                             | ``Term t = solver.mkTerm(Kind::TCLOSURE, X);``                                     |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Join                 | ``(join X Y)``                               | ``Term t = solver.mkTerm(Kind::JOIN, X, Y);``                                      |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
+| Product              | ``(product X Y)``                            | ``Term t = solver.mkTerm(Kind::PRODUCT, X, Y);``                                   |
++----------------------+----------------------------------------------+------------------------------------------------------------------------------------+
index f0b25aea44eb34a5e1e8567145a0738ddd73389e..2d2a949d53f07207a37cd55b20ca925c6d966db8 100644 (file)
@@ -6,3 +6,4 @@ Theory References
 
    theories/datatypes
    theories/separation-logic
+   theories/sets-and-relations
index 5c96527071aa014a602ec2fa9ab1049500db1e60..c1eded4a4a2f3029df24c8388607ba8b2a0e925f 100644 (file)
@@ -10,7 +10,7 @@
  * directory for licensing information.
  * ****************************************************************************
  *
- * A simple demonstration of reasoning about sets with CVC4.
+ * A simple demonstration of reasoning about sets with cvc5.
  */
 
 #include <cvc5/cvc5.h>
diff --git a/examples/api/smtlib/relations.smt2 b/examples/api/smtlib/relations.smt2
new file mode 100644 (file)
index 0000000..11801a8
--- /dev/null
@@ -0,0 +1,41 @@
+(set-logic ALL)
+(set-info :status sat)
+
+(declare-fun r1 () (Set (Tuple String Int)))
+(declare-fun r2 () (Set (Tuple Int String)))
+(declare-fun r () (Set (Tuple String String)))
+(declare-fun s () (Set (Tuple String String)))
+(declare-fun t () (Set (Tuple String Int Int String)))
+(declare-fun lt1 () (Set (Tuple Int Int)))
+(declare-fun lt2 () (Set (Tuple Int Int)))
+(declare-fun i () Int)
+
+(assert
+  (= r1
+    (insert
+      (mkTuple "a" 1)
+      (mkTuple "b" 2)
+      (mkTuple "c" 3)
+      (singleton (mkTuple "d" 4)))))
+(assert
+  (= r2
+    (insert
+      (mkTuple 1 "1")
+      (mkTuple 2 "2")
+      (mkTuple 3 "3")
+      (singleton (mkTuple 17 "17")))))
+(assert (= r (join r1 r2)))
+(assert (= s (transpose r)))
+(assert (= t (product r1 r2)))
+(assert
+  (=
+    lt1
+     (insert
+       (mkTuple 1 2)
+       (mkTuple 2 3)
+       (mkTuple 3 4)
+       (singleton (mkTuple 4 5)))))
+(assert (= lt2 (tclosure lt1)))
+(assert (= i (card t)))
+
+(check-sat)
diff --git a/examples/api/smtlib/sets.smt2 b/examples/api/smtlib/sets.smt2
new file mode 100644 (file)
index 0000000..437c285
--- /dev/null
@@ -0,0 +1,34 @@
+(set-logic QF_UFLIAFS)
+(set-option :produce-models true)
+(set-option :incremental true)
+(declare-const A (Set Int))
+(declare-const B (Set Int))
+(declare-const C (Set Int))
+(declare-const x Int)
+
+; Verify union distributions over intersection
+(check-sat-assuming
+  (
+    (distinct
+      (intersection (union A B) C)
+      (union (intersection A C) (intersection B C)))
+  )
+)
+
+; Verify emptset is a subset of any set
+(check-sat-assuming
+  (
+    (not (subset (as emptyset (Set Int)) A))
+  )
+)
+
+; Find an element in {1, 2} intersection {2, 3}, if there is one.
+(check-sat-assuming
+  (
+    (member
+      x
+      (intersection
+        (union (singleton 1) (singleton 2))
+        (union (singleton 2) (singleton 3))))
+  )
+)