Theory Reference: Sets and Relations 
Finite Sets 
cvc5 supports the theory of finite sets using the following sorts, constants, functions and predicates. More details can be found in [ BBRT17 ] .
For the C++ API examples in the table below, we assume that we have created a cvc5::Solver solver object.
| 
               SMTLIB language  | 
             
               C++ API  | 
            |
| 
               Logic String  | 
             
               append FS for finite sets 
                 | 
             
               append FS for finite sets 
                 | 
            
| 
               Sort  | 
             
               
                 | 
             
               
                 | 
            
| 
               Constants  | 
             
               
                 | 
             
               
                
                 | 
            
| 
               Union  | 
             
               
                 | 
             
               
                
                 | 
            
| 
               Intersection  | 
             
               
                 | 
             
               
                 | 
            
| 
               Minus  | 
             
               
                 | 
             
               
                 | 
            
| 
               Membership  | 
             
               
                 | 
             
               
                
                 | 
            
| 
               Subset  | 
             
               
                 | 
             
               
                 | 
            
| 
               Emptyset  | 
             
               
                 | 
             
               
                 | 
            
| 
               Singleton Set  | 
             
               
                 | 
             
               
                 | 
            
| 
               Cardinality  | 
             
               
                 | 
             
               
                 | 
            
| 
               Insert / Finite Sets  | 
             
               
                 | 
             
               
                
                
                
                
                 | 
            
| 
               Complement  | 
             
               
                 | 
             
               
                 | 
            
| 
               Universe Set  | 
             
               
                 | 
             
               
                 | 
            
Semantics 
            The semantics of most of the above operators (e.g.,
            
             
              set.union
             
            
            ,
            
             
              set.inter
             
            
            , difference) are straightforward.
The semantics for the universe set and complement are more subtle and explained
in the following.
           
            The universe set
            
             
              (as
             
             
              set.universe
             
             
              (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:
(declare-fun x () (Set Int))
(declare-fun y () (Set Int))
(declare-fun z () (Set Int))
(assert (set.member 0 x))
(assert (set.member 1 y))
(assert (= z (as set.universe (Set Int))))
(check-sat)
            Here, a possible model is:
(define-fun x () (set.singleton 0))
(define-fun y () (set.singleton 1))
(define-fun z () (set.union (set.singleton 1) (set.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
            
             
              (=
             
             
              (set.complement
             
             
              X)
             
             
              (set.minus
             
             
              (as
             
             
              set.universe
             
             
              (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):
(set-logic ALL)
(declare-fun x () (Set Int))
(assert (forall ((z Int) (set.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.
Below is a more extensive example on how to use finite sets:
 1/******************************************************************************
 2 * Top contributors (to current version):
 3 *   Aina Niemetz, Kshitij Bansal, Mathias Preiner
 4 *
 5 * This file is part of the cvc5 project.
 6 *
 7 * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
 8 * in the top-level source directory and their institutional affiliations.
 9 * All rights reserved.  See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
12 *
13 * A simple demonstration of reasoning about sets with cvc5.
14 */
15
16#include <cvc5/cvc5.h>
17
18#include <iostream>
19
20using namespace std;
21using namespace cvc5;
22
23int main()
24{
25  Solver slv;
26
27  // Optionally, set the logic. We need at least UF for equality predicate,
28  // integers (LIA) and sets (FS).
29  slv.setLogic("QF_UFLIAFS");
30
31  // Produce models
32  slv.setOption("produce-models", "true");
33  slv.setOption("output-language", "smt2");
34
35  Sort integer = slv.getIntegerSort();
36  Sort set = slv.mkSetSort(integer);
37
38  // Verify union distributions over intersection
39  // (A union B) intersection C = (A intersection C) union (B intersection C)
40  {
41    Term A = slv.mkConst(set, "A");
42    Term B = slv.mkConst(set, "B");
43    Term C = slv.mkConst(set, "C");
44
45    Term unionAB = slv.mkTerm(Kind::SET_UNION, {A, B});
46    Term lhs = slv.mkTerm(Kind::SET_INTER, {unionAB, C});
47
48    Term intersectionAC = slv.mkTerm(Kind::SET_INTER, {A, C});
49    Term intersectionBC = slv.mkTerm(Kind::SET_INTER, {B, C});
50    Term rhs = slv.mkTerm(Kind::SET_UNION, {intersectionAC, intersectionBC});
51
52    Term theorem = slv.mkTerm(Kind::EQUAL, {lhs, rhs});
53
54    cout << "cvc5 reports: " << theorem << " is "
55         << slv.checkSatAssuming(theorem.notTerm()) << "." << endl;
56  }
57
58  // Verify emptset is a subset of any set
59  {
60    Term A = slv.mkConst(set, "A");
61    Term emptyset = slv.mkEmptySet(set);
62
63    Term theorem = slv.mkTerm(Kind::SET_SUBSET, {emptyset, A});
64
65    cout << "cvc5 reports: " << theorem << " is "
66         << slv.checkSatAssuming(theorem.notTerm()) << "." << endl;
67  }
68
69  // Find me an element in {1, 2} intersection {2, 3}, if there is one.
70  {
71    Term one = slv.mkInteger(1);
72    Term two = slv.mkInteger(2);
73    Term three = slv.mkInteger(3);
74
75    Term singleton_one = slv.mkTerm(Kind::SET_SINGLETON, {one});
76    Term singleton_two = slv.mkTerm(Kind::SET_SINGLETON, {two});
77    Term singleton_three = slv.mkTerm(Kind::SET_SINGLETON, {three});
78    Term one_two = slv.mkTerm(Kind::SET_UNION, {singleton_one, singleton_two});
79    Term two_three =
80        slv.mkTerm(Kind::SET_UNION, {singleton_two, singleton_three});
81    Term intersection = slv.mkTerm(Kind::SET_INTER, {one_two, two_three});
82
83    Term x = slv.mkConst(integer, "x");
84
85    Term e = slv.mkTerm(Kind::SET_MEMBER, {x, intersection});
86
87    Result result = slv.checkSatAssuming(e);
88    cout << "cvc5 reports: " << e << " is " << result << "." << endl;
89
90    if (result.isSat())
91    {
92      cout << "For instance, " << slv.getValue(x) << " is a member." << endl;
93    }
94  }
95}
               1/******************************************************************************
 2 * Top contributors (to current version):
 3 *   Mudathir Mohamed, Andres Noetzli
 4 *
 5 * This file is part of the cvc5 project.
 6 *
 7 * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
 8 * in the top-level source directory and their institutional affiliations.
 9 * All rights reserved.  See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
12 *
13 * A simple demonstration of reasoning about sets with cvc5.
14 */
15
16import static io.github.cvc5.Kind.*;
17
18import io.github.cvc5.*;
19
20public class Sets
21{
22  public static void main(String args[]) throws CVC5ApiException
23  {
24    Solver slv = new Solver();
25    {
26      // Optionally, set the logic. We need at least UF for equality predicate,
27      // integers (LIA) and sets (FS).
28      slv.setLogic("QF_UFLIAFS");
29
30      // Produce models
31      slv.setOption("produce-models", "true");
32      slv.setOption("output-language", "smt2");
33
34      Sort integer = slv.getIntegerSort();
35      Sort set = slv.mkSetSort(integer);
36
37      // Verify union distributions over intersection
38      // (A union B) intersection C = (A intersection C) union (B intersection C)
39      {
40        Term A = slv.mkConst(set, "A");
41        Term B = slv.mkConst(set, "B");
42        Term C = slv.mkConst(set, "C");
43
44        Term unionAB = slv.mkTerm(SET_UNION, A, B);
45        Term lhs = slv.mkTerm(SET_INTER, unionAB, C);
46
47        Term intersectionAC = slv.mkTerm(SET_INTER, A, C);
48        Term intersectionBC = slv.mkTerm(SET_INTER, B, C);
49        Term rhs = slv.mkTerm(SET_UNION, intersectionAC, intersectionBC);
50
51        Term theorem = slv.mkTerm(EQUAL, lhs, rhs);
52
53        System.out.println(
54            "cvc5 reports: " + theorem + " is " + slv.checkSatAssuming(theorem.notTerm()) + ".");
55      }
56
57      // Verify set.empty is a subset of any set
58      {
59        Term A = slv.mkConst(set, "A");
60        Term emptyset = slv.mkEmptySet(set);
61
62        Term theorem = slv.mkTerm(SET_SUBSET, emptyset, A);
63
64        System.out.println(
65            "cvc5 reports: " + theorem + " is " + slv.checkSatAssuming(theorem.notTerm()) + ".");
66      }
67
68      // Find me an element in {1, 2} intersection {2, 3}, if there is one.
69      {
70        Term one = slv.mkInteger(1);
71        Term two = slv.mkInteger(2);
72        Term three = slv.mkInteger(3);
73
74        Term singleton_one = slv.mkTerm(SET_SINGLETON, one);
75        Term singleton_two = slv.mkTerm(SET_SINGLETON, two);
76        Term singleton_three = slv.mkTerm(SET_SINGLETON, three);
77        Term one_two = slv.mkTerm(SET_UNION, singleton_one, singleton_two);
78        Term two_three = slv.mkTerm(SET_UNION, singleton_two, singleton_three);
79        Term intersection = slv.mkTerm(SET_INTER, one_two, two_three);
80
81        Term x = slv.mkConst(integer, "x");
82
83        Term e = slv.mkTerm(SET_MEMBER, x, intersection);
84
85        Result result = slv.checkSatAssuming(e);
86        System.out.println("cvc5 reports: " + e + " is " + result + ".");
87
88        if (result.isSat())
89        {
90          System.out.println("For instance, " + slv.getValue(x) + " is a member.");
91        }
92      }
93    }
94    Context.deletePointers();
95  }
96}
               1#!/usr/bin/env python
 2###############################################################################
 3# Top contributors (to current version):
 4#   Makai Mann, Aina Niemetz, Mudathir Mohamed
 5#
 6# This file is part of the cvc5 project.
 7#
 8# Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
 9# in the top-level source directory and their institutional affiliations.
10# All rights reserved.  See the file COPYING in the top-level source
11# directory for licensing information.
12# #############################################################################
13#
14# A simple demonstration of the solving capabilities of the cvc5 sets solver
15# through the Python API. This is a direct translation of sets.cpp.
16##
17
18import cvc5
19from cvc5 import Kind
20
21if __name__ == "__main__":
22    slv = cvc5.Solver()
23
24    # Optionally, set the logic. We need at least UF for equality predicate,
25    # integers (LIA) and sets (FS).
26    slv.setLogic("QF_UFLIAFS")
27
28    # Produce models
29    slv.setOption("produce-models", "true")
30    slv.setOption("output-language", "smt2")
31
32    integer = slv.getIntegerSort()
33    set_ = slv.mkSetSort(integer)
34
35    # Verify union distributions over intersection
36    # (A union B) intersection C = (A intersection C) union (B intersection C)
37
38    A = slv.mkConst(set_, "A")
39    B = slv.mkConst(set_, "B")
40    C = slv.mkConst(set_, "C")
41
42    unionAB = slv.mkTerm(Kind.SET_UNION, A, B)
43    lhs = slv.mkTerm(Kind.SET_INTER, unionAB, C)
44
45    intersectionAC = slv.mkTerm(Kind.SET_INTER, A, C)
46    intersectionBC = slv.mkTerm(Kind.SET_INTER, B, C)
47    rhs = slv.mkTerm(Kind.SET_UNION, intersectionAC, intersectionBC)
48
49    theorem = slv.mkTerm(Kind.EQUAL, lhs, rhs)
50
51    print("cvc5 reports: {} is {}".format(
52        theorem.notTerm(), slv.checkSatAssuming(theorem.notTerm())))
53
54    # Verify emptset is a subset of any set
55
56    A = slv.mkConst(set_, "A")
57    emptyset = slv.mkEmptySet(set_)
58
59    theorem = slv.mkTerm(Kind.SET_SUBSET, emptyset, A)
60
61    print("cvc5 reports: {} is {}".format(
62        theorem.notTerm(), slv.checkSatAssuming(theorem.notTerm())))
63
64    # Find me an element in 1, 2 intersection 2, 3, if there is one.
65
66    one = slv.mkInteger(1)
67    two = slv.mkInteger(2)
68    three = slv.mkInteger(3)
69
70    singleton_one = slv.mkTerm(Kind.SET_SINGLETON, one)
71    singleton_two = slv.mkTerm(Kind.SET_SINGLETON, two)
72    singleton_three = slv.mkTerm(Kind.SET_SINGLETON, three)
73    one_two = slv.mkTerm(Kind.SET_UNION, singleton_one, singleton_two)
74    two_three = slv.mkTerm(Kind.SET_UNION, singleton_two, singleton_three)
75    intersection = slv.mkTerm(Kind.SET_INTER, one_two, two_three)
76
77    x = slv.mkConst(integer, "x")
78
79    e = slv.mkTerm(Kind.SET_MEMBER, x, intersection)
80
81    result = slv.checkSatAssuming(e)
82
83    print("cvc5 reports: {} is {}".format(e, result))
84
85    if result:
86        print("For instance, {} is a member".format(slv.getValue(x)))
               1(set-logic QF_UFLIAFS)
 2(set-option :produce-models true)
 3(set-option :incremental true)
 4(declare-const A (Set Int))
 5(declare-const B (Set Int))
 6(declare-const C (Set Int))
 7(declare-const x Int)
 8
 9; Verify union distributions over intersection
10(check-sat-assuming
11  (
12    (distinct
13      (set.inter (set.union A B) C)
14      (set.union (set.inter A C) (set.inter B C)))
15  )
16)
17
18; Verify emptset is a subset of any set
19(check-sat-assuming
20  (
21    (not (set.subset (as set.empty (Set Int)) A))
22  )
23)
24
25; Find an element in {1, 2} intersection {2, 3}, if there is one.
26(check-sat-assuming
27  (
28    (set.member
29      x
30      (set.inter
31        (set.union (set.singleton 1) (set.singleton 2))
32        (set.union (set.singleton 2) (set.singleton 3))))
33  )
34)
35
36(echo "A member: ")
37(get-value (x))
              Finite Relations 
cvc5 also supports the theory of finite relations, using the following sorts, constants, functions and predicates. More details can be found in [ MRTB17 ] .
| 
               SMTLIB language  | 
             
               C++ API  | 
            |
| 
               Logic String  | 
             
               
                 | 
             
               
                 | 
            
| 
               Tuple Sort  | 
             
               
                 | 
             
               
                
                 | 
            
| 
               
                 | 
             
               
                
                
                 | 
            |
| 
               Tuple Constructor  | 
             
               
                 | 
             
               
                 | 
            
| 
               Unit Tuple Sort  | 
             
               
                 | 
             
               
                 | 
            
| 
               Unit Tuple  | 
             
               
                 | 
             
               
                 | 
            
| 
               Tuple Selector  | 
             
               
                 | 
             
               
                
                
                
                 | 
            
| 
               Relation Sort  | 
             
               
                which is a syntax sugar for 
                 | 
             
               
                 | 
            
| 
               Constants  | 
             
               
                 | 
             
               
                
                 | 
            
| 
               Transpose  | 
             
               
                 | 
             
               
                 | 
            
| 
               Transitive Closure  | 
             
               
                 | 
             
               
                 | 
            
| 
               Join  | 
             
               
                 | 
             
               
                 | 
            
| 
               Product  | 
             
               
                 | 
             
               
                 | 
            
Example:
examples/api/cpp/relations.cpp
  1/******************************************************************************
  2 * Top contributors (to current version):
  3 *   Mudathir Mohamed, Mathias Preiner
  4 *
  5 * This file is part of the cvc5 project.
  6 *
  7 * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  8 * in the top-level source directory and their institutional affiliations.
  9 * All rights reserved.  See the file COPYING in the top-level source
 10 * directory for licensing information.
 11 * ****************************************************************************
 12 *
 13 * A simple demonstration of reasoning about relations with cvc5 via C++ API.
 14 */
 15
 16#include <cvc5/cvc5.h>
 17
 18#include <iostream>
 19
 20using namespace cvc5;
 21
 22int main()
 23{
 24  Solver solver;
 25
 26  // Set the logic
 27  solver.setLogic("ALL");
 28
 29  // options
 30  solver.setOption("produce-models", "true");
 31  // we need finite model finding to answer sat problems with universal
 32  // quantified formulas
 33  solver.setOption("finite-model-find", "true");
 34  // we need sets extension to support set.universe operator
 35  solver.setOption("sets-ext", "true");
 36
 37  // (declare-sort Person 0)
 38  Sort personSort = solver.mkUninterpretedSort("Person");
 39
 40  // (Tuple Person)
 41  Sort tupleArity1 = solver.mkTupleSort({personSort});
 42  // (Relation Person)
 43  Sort relationArity1 = solver.mkSetSort(tupleArity1);
 44
 45  // (Tuple Person Person)
 46  Sort tupleArity2 = solver.mkTupleSort({personSort, personSort});
 47  // (Relation Person Person)
 48  Sort relationArity2 = solver.mkSetSort(tupleArity2);
 49
 50  // empty set
 51  Term emptySetTerm = solver.mkEmptySet(relationArity1);
 52
 53  // empty relation
 54  Term emptyRelationTerm = solver.mkEmptySet(relationArity2);
 55
 56  // universe set
 57  Term universeSet = solver.mkUniverseSet(relationArity1);
 58
 59  // variables
 60  Term people = solver.mkConst(relationArity1, "people");
 61  Term males = solver.mkConst(relationArity1, "males");
 62  Term females = solver.mkConst(relationArity1, "females");
 63  Term father = solver.mkConst(relationArity2, "father");
 64  Term mother = solver.mkConst(relationArity2, "mother");
 65  Term parent = solver.mkConst(relationArity2, "parent");
 66  Term ancestor = solver.mkConst(relationArity2, "ancestor");
 67  Term descendant = solver.mkConst(relationArity2, "descendant");
 68
 69  Term isEmpty1 = solver.mkTerm(Kind::EQUAL, {males, emptySetTerm});
 70  Term isEmpty2 = solver.mkTerm(Kind::EQUAL, {females, emptySetTerm});
 71
 72  // (assert (= people (as set.universe (Relation Person))))
 73  Term peopleAreTheUniverse = solver.mkTerm(Kind::EQUAL, {people, universeSet});
 74  // (assert (not (= males (as set.empty (Relation Person)))))
 75  Term maleSetIsNotEmpty = solver.mkTerm(Kind::NOT, {isEmpty1});
 76  // (assert (not (= females (as set.empty (Relation Person)))))
 77  Term femaleSetIsNotEmpty = solver.mkTerm(Kind::NOT, {isEmpty2});
 78
 79  // (assert (= (set.inter males females)
 80  //            (as set.empty (Relation Person))))
 81  Term malesFemalesIntersection =
 82      solver.mkTerm(Kind::SET_INTER, {males, females});
 83  Term malesAndFemalesAreDisjoint =
 84      solver.mkTerm(Kind::EQUAL, {malesFemalesIntersection, emptySetTerm});
 85
 86  // (assert (not (= father (as set.empty (Relation Person Person)))))
 87  // (assert (not (= mother (as set.empty (Relation Person Person)))))
 88  Term isEmpty3 = solver.mkTerm(Kind::EQUAL, {father, emptyRelationTerm});
 89  Term isEmpty4 = solver.mkTerm(Kind::EQUAL, {mother, emptyRelationTerm});
 90  Term fatherIsNotEmpty = solver.mkTerm(Kind::NOT, {isEmpty3});
 91  Term motherIsNotEmpty = solver.mkTerm(Kind::NOT, {isEmpty4});
 92
 93  // fathers are males
 94  // (assert (set.subset (rel.join father people) males))
 95  Term fathers = solver.mkTerm(Kind::RELATION_JOIN, {father, people});
 96  Term fathersAreMales = solver.mkTerm(Kind::SET_SUBSET, {fathers, males});
 97
 98  // mothers are females
 99  // (assert (set.subset (rel.join mother people) females))
100  Term mothers = solver.mkTerm(Kind::RELATION_JOIN, {mother, people});
101  Term mothersAreFemales = solver.mkTerm(Kind::SET_SUBSET, {mothers, females});
102
103  // (assert (= parent (set.union father mother)))
104  Term unionFatherMother = solver.mkTerm(Kind::SET_UNION, {father, mother});
105  Term parentIsFatherOrMother =
106      solver.mkTerm(Kind::EQUAL, {parent, unionFatherMother});
107
108  // (assert (= ancestor (rel.tclosure parent)))
109  Term transitiveClosure = solver.mkTerm(Kind::RELATION_TCLOSURE, {parent});
110  Term ancestorFormula =
111      solver.mkTerm(Kind::EQUAL, {ancestor, transitiveClosure});
112
113  // (assert (= descendant (rel.transpose descendant)))
114  Term transpose = solver.mkTerm(Kind::RELATION_TRANSPOSE, {ancestor});
115  Term descendantFormula = solver.mkTerm(Kind::EQUAL, {descendant, transpose});
116
117  // (assert (forall ((x Person)) (not (set.member (tuple x x) ancestor))))
118  Term x = solver.mkVar(personSort, "x");
119  Term xxTuple = solver.mkTuple({x, x});
120  Term member = solver.mkTerm(Kind::SET_MEMBER, {xxTuple, ancestor});
121  Term notMember = solver.mkTerm(Kind::NOT, {member});
122
123  Term quantifiedVariables = solver.mkTerm(Kind::VARIABLE_LIST, {x});
124  Term noSelfAncestor =
125      solver.mkTerm(Kind::FORALL, {quantifiedVariables, notMember});
126
127  // formulas
128  solver.assertFormula(peopleAreTheUniverse);
129  solver.assertFormula(maleSetIsNotEmpty);
130  solver.assertFormula(femaleSetIsNotEmpty);
131  solver.assertFormula(malesAndFemalesAreDisjoint);
132  solver.assertFormula(fatherIsNotEmpty);
133  solver.assertFormula(motherIsNotEmpty);
134  solver.assertFormula(fathersAreMales);
135  solver.assertFormula(mothersAreFemales);
136  solver.assertFormula(parentIsFatherOrMother);
137  solver.assertFormula(descendantFormula);
138  solver.assertFormula(ancestorFormula);
139  solver.assertFormula(noSelfAncestor);
140
141  // check sat
142  Result result = solver.checkSat();
143
144  // output
145  std::cout << "Result     = " << result << std::endl;
146  std::cout << "people     = " << solver.getValue(people) << std::endl;
147  std::cout << "males      = " << solver.getValue(males) << std::endl;
148  std::cout << "females    = " << solver.getValue(females) << std::endl;
149  std::cout << "father     = " << solver.getValue(father) << std::endl;
150  std::cout << "mother     = " << solver.getValue(mother) << std::endl;
151  std::cout << "parent     = " << solver.getValue(parent) << std::endl;
152  std::cout << "descendant = " << solver.getValue(descendant) << std::endl;
153  std::cout << "ancestor   = " << solver.getValue(ancestor) << std::endl;
154}
             examples/api/java/Relations.java
  1/******************************************************************************
  2 * Top contributors (to current version):
  3 *   Mudathir Mohamed, Andres Noetzli, Aina Niemetz
  4 *
  5 * This file is part of the cvc5 project.
  6 *
  7 * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  8 * in the top-level source directory and their institutional affiliations.
  9 * All rights reserved.  See the file COPYING in the top-level source
 10 * directory for licensing information.
 11 * ****************************************************************************
 12 *
 13 * A simple demonstration of reasoning about relations with cvc5 via Java API.
 14 */
 15
 16import static io.github.cvc5.Kind.*;
 17
 18import io.github.cvc5.*;
 19
 20public class Relations
 21{
 22  public static void main(String[] args) throws CVC5ApiException
 23  {
 24    Solver solver = new Solver();
 25    {
 26      // Set the logic
 27      solver.setLogic("ALL");
 28
 29      // options
 30      solver.setOption("produce-models", "true");
 31      // we need finite model finding to answer sat problems with universal
 32      // quantified formulas
 33      solver.setOption("finite-model-find", "true");
 34      // we need sets extension to support set.universe operator
 35      solver.setOption("sets-ext", "true");
 36
 37      // (declare-sort Person 0)
 38      Sort personSort = solver.mkUninterpretedSort("Person");
 39
 40      // (Tuple Person)
 41      Sort tupleArity1 = solver.mkTupleSort(new Sort[] {personSort});
 42      // (Relation Person)
 43      Sort relationArity1 = solver.mkSetSort(tupleArity1);
 44
 45      // (Tuple Person Person)
 46      Sort tupleArity2 = solver.mkTupleSort(new Sort[] {personSort, personSort});
 47      // (Relation Person Person)
 48      Sort relationArity2 = solver.mkSetSort(tupleArity2);
 49
 50      // empty set
 51      Term emptySetTerm = solver.mkEmptySet(relationArity1);
 52
 53      // empty relation
 54      Term emptyRelationTerm = solver.mkEmptySet(relationArity2);
 55
 56      // universe set
 57      Term universeSet = solver.mkUniverseSet(relationArity1);
 58
 59      // variables
 60      Term people = solver.mkConst(relationArity1, "people");
 61      Term males = solver.mkConst(relationArity1, "males");
 62      Term females = solver.mkConst(relationArity1, "females");
 63      Term father = solver.mkConst(relationArity2, "father");
 64      Term mother = solver.mkConst(relationArity2, "mother");
 65      Term parent = solver.mkConst(relationArity2, "parent");
 66      Term ancestor = solver.mkConst(relationArity2, "ancestor");
 67      Term descendant = solver.mkConst(relationArity2, "descendant");
 68
 69      Term isEmpty1 = solver.mkTerm(EQUAL, males, emptySetTerm);
 70      Term isEmpty2 = solver.mkTerm(EQUAL, females, emptySetTerm);
 71
 72      // (assert (= people (as set.universe (Relation Person))))
 73      Term peopleAreTheUniverse = solver.mkTerm(EQUAL, people, universeSet);
 74      // (assert (not (= males (as set.empty (Relation Person)))))
 75      Term maleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty1);
 76      // (assert (not (= females (as set.empty (Relation Person)))))
 77      Term femaleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty2);
 78
 79      // (assert (= (set.inter males females)
 80      //            (as set.empty (Relation Person))))
 81      Term malesFemalesIntersection = solver.mkTerm(SET_INTER, males, females);
 82      Term malesAndFemalesAreDisjoint =
 83          solver.mkTerm(EQUAL, malesFemalesIntersection, emptySetTerm);
 84
 85      // (assert (not (= father (as set.empty (Relation Person Person)))))
 86      // (assert (not (= mother (as set.empty (Relation Person Person)))))
 87      Term isEmpty3 = solver.mkTerm(EQUAL, father, emptyRelationTerm);
 88      Term isEmpty4 = solver.mkTerm(EQUAL, mother, emptyRelationTerm);
 89      Term fatherIsNotEmpty = solver.mkTerm(NOT, isEmpty3);
 90      Term motherIsNotEmpty = solver.mkTerm(NOT, isEmpty4);
 91
 92      // fathers are males
 93      // (assert (set.subset (rel.join father people) males))
 94      Term fathers = solver.mkTerm(RELATION_JOIN, father, people);
 95      Term fathersAreMales = solver.mkTerm(SET_SUBSET, fathers, males);
 96
 97      // mothers are females
 98      // (assert (set.subset (rel.join mother people) females))
 99      Term mothers = solver.mkTerm(RELATION_JOIN, mother, people);
100      Term mothersAreFemales = solver.mkTerm(SET_SUBSET, mothers, females);
101
102      // (assert (= parent (set.union father mother)))
103      Term unionFatherMother = solver.mkTerm(SET_UNION, father, mother);
104      Term parentIsFatherOrMother = solver.mkTerm(EQUAL, parent, unionFatherMother);
105
106      // (assert (= ancestor (rel.tclosure parent)))
107      Term transitiveClosure = solver.mkTerm(RELATION_TCLOSURE, parent);
108      Term ancestorFormula = solver.mkTerm(EQUAL, ancestor, transitiveClosure);
109
110      // (assert (= descendant (rel.transpose ancestor)))
111      Term transpose = solver.mkTerm(RELATION_TRANSPOSE, ancestor);
112      Term descendantFormula = solver.mkTerm(EQUAL, descendant, transpose);
113
114      // (assert (forall ((x Person)) (not (set.member (tuple x x) ancestor))))
115      Term x = solver.mkVar(personSort, "x");
116      Term xxTuple = solver.mkTuple(new Term[] {x, x});
117      Term member = solver.mkTerm(SET_MEMBER, xxTuple, ancestor);
118      Term notMember = solver.mkTerm(NOT, member);
119
120      Term quantifiedVariables = solver.mkTerm(VARIABLE_LIST, x);
121      Term noSelfAncestor = solver.mkTerm(FORALL, quantifiedVariables, notMember);
122
123      // formulas
124      solver.assertFormula(peopleAreTheUniverse);
125      solver.assertFormula(maleSetIsNotEmpty);
126      solver.assertFormula(femaleSetIsNotEmpty);
127      solver.assertFormula(malesAndFemalesAreDisjoint);
128      solver.assertFormula(fatherIsNotEmpty);
129      solver.assertFormula(motherIsNotEmpty);
130      solver.assertFormula(fathersAreMales);
131      solver.assertFormula(mothersAreFemales);
132      solver.assertFormula(parentIsFatherOrMother);
133      solver.assertFormula(descendantFormula);
134      solver.assertFormula(ancestorFormula);
135      solver.assertFormula(noSelfAncestor);
136
137      // check sat
138      Result result = solver.checkSat();
139
140      // output
141      System.out.println("Result     = " + result);
142      System.out.println("people     = " + solver.getValue(people));
143      System.out.println("males      = " + solver.getValue(males));
144      System.out.println("females    = " + solver.getValue(females));
145      System.out.println("father     = " + solver.getValue(father));
146      System.out.println("mother     = " + solver.getValue(mother));
147      System.out.println("parent     = " + solver.getValue(parent));
148      System.out.println("descendant = " + solver.getValue(descendant));
149      System.out.println("ancestor   = " + solver.getValue(ancestor));
150    }
151    Context.deletePointers();
152  }
153}
             examples/api/python/relations.py
  1#!/usr/bin/env python
  2###############################################################################
  3# Top contributors (to current version):
  4#   Mudathir Mohamed, Aina Niemetz, Alex Ozdemir
  5#
  6# This file is part of the cvc5 project.
  7#
  8# Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
  9# in the top-level source directory and their institutional affiliations.
 10# All rights reserved.  See the file COPYING in the top-level source
 11# directory for licensing information.
 12# #############################################################################
 13#
 14# A simple demonstration of the solving capabilities of the cvc5 relations solver
 15# through the Python API. This is a direct translation of relations.cpp.
 16##
 17
 18import cvc5
 19from cvc5 import Kind
 20
 21if __name__ == "__main__":
 22    solver = cvc5.Solver()
 23
 24    # Set the logic
 25    solver.setLogic("ALL")
 26
 27    # options
 28    solver.setOption("produce-models", "true")
 29    # we need finite model finding to answer sat problems with universal
 30    # quantified formulas
 31    solver.setOption("finite-model-find", "true")
 32    # we need sets extension to support set.universe operator
 33    solver.setOption("sets-ext", "true")
 34
 35    integer = solver.getIntegerSort()
 36    set_ = solver.mkSetSort(integer)
 37
 38    # Verify union distributions over intersection
 39    # (A union B) intersection C = (A intersection C) union (B intersection C)
 40
 41    # (declare-sort Person 0)
 42    personSort = solver.mkUninterpretedSort("Person")
 43
 44    # (Tuple Person)
 45    tupleArity1 = solver.mkTupleSort(personSort)
 46    # (Relation Person)
 47    relationArity1 = solver.mkSetSort(tupleArity1)
 48
 49    # (Tuple Person Person)
 50    tupleArity2 = solver.mkTupleSort(personSort, personSort)
 51    # (Relation Person Person)
 52    relationArity2 = solver.mkSetSort(tupleArity2)
 53
 54    # empty set
 55    emptySetTerm = solver.mkEmptySet(relationArity1)
 56
 57    # empty relation
 58    emptyRelationTerm = solver.mkEmptySet(relationArity2)
 59
 60    # universe set
 61    universeSet = solver.mkUniverseSet(relationArity1)
 62
 63    # variables
 64    people = solver.mkConst(relationArity1, "people")
 65    males = solver.mkConst(relationArity1, "males")
 66    females = solver.mkConst(relationArity1, "females")
 67    father = solver.mkConst(relationArity2, "father")
 68    mother = solver.mkConst(relationArity2, "mother")
 69    parent = solver.mkConst(relationArity2, "parent")
 70    ancestor = solver.mkConst(relationArity2, "ancestor")
 71    descendant = solver.mkConst(relationArity2, "descendant")
 72
 73    isEmpty1 = solver.mkTerm(Kind.EQUAL, males, emptySetTerm)
 74    isEmpty2 = solver.mkTerm(Kind.EQUAL, females, emptySetTerm)
 75
 76    # (assert (= people (as set.universe (Relation Person))))
 77    peopleAreTheUniverse = solver.mkTerm(Kind.EQUAL, people, universeSet)
 78    # (assert (not (= males (as set.empty (Relation Person)))))
 79    maleSetIsNotEmpty = solver.mkTerm(Kind.NOT, isEmpty1)
 80    # (assert (not (= females (as set.empty (Relation Person)))))
 81    femaleSetIsNotEmpty = solver.mkTerm(Kind.NOT, isEmpty2)
 82
 83    # (assert (= (set.inter males females)
 84    #            (as set.empty (Relation Person))))
 85    malesFemalesIntersection = solver.mkTerm(Kind.SET_INTER, males, females)
 86    malesAndFemalesAreDisjoint = \
 87            solver.mkTerm(Kind.EQUAL, malesFemalesIntersection, emptySetTerm)
 88
 89    # (assert (not (= father (as set.empty (Relation Person Person)))))
 90    # (assert (not (= mother (as set.empty (Relation Person Person)))))
 91    isEmpty3 = solver.mkTerm(Kind.EQUAL, father, emptyRelationTerm)
 92    isEmpty4 = solver.mkTerm(Kind.EQUAL, mother, emptyRelationTerm)
 93    fatherIsNotEmpty = solver.mkTerm(Kind.NOT, isEmpty3)
 94    motherIsNotEmpty = solver.mkTerm(Kind.NOT, isEmpty4)
 95
 96    # fathers are males
 97    # (assert (set.subset (rel.join father people) males))
 98    fathers = solver.mkTerm(Kind.RELATION_JOIN, father, people)
 99    fathersAreMales = solver.mkTerm(Kind.SET_SUBSET, fathers, males)
100
101    # mothers are females
102    # (assert (set.subset (rel.join mother people) females))
103    mothers = solver.mkTerm(Kind.RELATION_JOIN, mother, people)
104    mothersAreFemales = solver.mkTerm(Kind.SET_SUBSET, mothers, females)
105
106    # (assert (= parent (set.union father mother)))
107    unionFatherMother = solver.mkTerm(Kind.SET_UNION, father, mother)
108    parentIsFatherOrMother = \
109            solver.mkTerm(Kind.EQUAL, parent, unionFatherMother)
110
111    # (assert (= ancestor (rel.tclosure parent)))
112    transitiveClosure = solver.mkTerm(Kind.RELATION_TCLOSURE, parent)
113    ancestorFormula = solver.mkTerm(Kind.EQUAL, ancestor, transitiveClosure)
114
115    # (assert (= descendant (rel.transpose ancestor)))
116    transpose = solver.mkTerm(Kind.RELATION_TRANSPOSE, ancestor)
117    descendantFormula = solver.mkTerm(Kind.EQUAL, descendant, transpose)
118
119    # (assert (forall ((x Person)) (not (set.member (tuple x x) ancestor))))
120    x = solver.mkVar(personSort, "x")
121    xxTuple = solver.mkTuple([x, x])
122    member = solver.mkTerm(Kind.SET_MEMBER, xxTuple, ancestor)
123    notMember = solver.mkTerm(Kind.NOT, member)
124
125    quantifiedVariables = solver.mkTerm(Kind.VARIABLE_LIST, x)
126    noSelfAncestor = solver.mkTerm(Kind.FORALL, quantifiedVariables, notMember)
127
128    # formulas
129    solver.assertFormula(peopleAreTheUniverse)
130    solver.assertFormula(maleSetIsNotEmpty)
131    solver.assertFormula(femaleSetIsNotEmpty)
132    solver.assertFormula(malesAndFemalesAreDisjoint)
133    solver.assertFormula(fatherIsNotEmpty)
134    solver.assertFormula(motherIsNotEmpty)
135    solver.assertFormula(fathersAreMales)
136    solver.assertFormula(mothersAreFemales)
137    solver.assertFormula(parentIsFatherOrMother)
138    solver.assertFormula(descendantFormula)
139    solver.assertFormula(ancestorFormula)
140    solver.assertFormula(noSelfAncestor)
141
142    # check sat
143    result = solver.checkSat()
144
145    # output
146    print("Result     = {}".format(result))
147    print("people     = {}".format(solver.getValue(people)))
148    print("males      = {}".format(solver.getValue(males)))
149    print("females    = {}".format(solver.getValue(females)))
150    print("father     = {}".format(solver.getValue(father)))
151    print("mother     = {}".format(solver.getValue(mother)))
152    print("parent     = {}".format(solver.getValue(parent)))
153    print("descendant = {}".format(solver.getValue(descendant)))
154    print("ancestor   = {}".format(solver.getValue(ancestor)))
             examples/api/smtlib/relations.smt2
 1(set-logic ALL)
 2
 3(set-option :produce-models true)
 4; we need finite model finding to answer sat problems with universal
 5; quantified formulas
 6(set-option :finite-model-find true)
 7; we need sets extension to support set.universe operator
 8(set-option :sets-ext true)
 9
10(declare-sort Person 0)
11
12(declare-fun people () (Relation Person))
13(declare-fun males () (Relation Person))
14(declare-fun females () (Relation Person))
15(declare-fun father () (Relation Person Person))
16(declare-fun mother () (Relation Person Person))
17(declare-fun parent () (Relation Person Person))
18(declare-fun ancestor () (Relation Person Person))
19(declare-fun descendant () (Relation Person Person))
20
21(assert (= people (as set.universe (Relation Person))))
22(assert (not (= males (as set.empty (Relation Person)))))
23(assert (not (= females (as set.empty (Relation Person)))))
24(assert (= (set.inter males females) (as set.empty (Relation Person))))
25
26; father relation is not empty
27(assert (not (= father (as set.empty (Relation Person Person)))))
28; mother relation is not empty
29(assert (not (= mother (as set.empty (Relation Person Person)))))
30; fathers are males
31(assert (set.subset (rel.join father people) males))
32; mothers are females
33(assert (set.subset (rel.join mother people) females))
34; parent
35(assert (= parent (set.union father mother)))
36; no self ancestor
37(assert (forall ((x Person)) (not (set.member (tuple x x) ancestor))))
38; ancestor
39(assert (= ancestor (rel.tclosure parent)))
40; ancestor
41(assert (= descendant (rel.transpose ancestor)))
42
43(check-sat)
44(get-model)