Theory Combination

examples/api/cpp/combination.cpp

  1 /******************************************************************************
  2  * Top contributors (to current version):
  3  *   Aina Niemetz, Mathias Preiner, Tim King
  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 the capabilities of cvc5
 14  *
 15  * A simple demonstration of how to use uninterpreted functions, combining this
 16  * with arithmetic, and extracting a model at the end of a satisfiable query.
 17  * The model is displayed using getValue().
 18  */
 19 
 20 #include <cvc5/cvc5.h>
 21 
 22 #include <iostream>
 23 
 24 using namespace std;
 25 using namespace cvc5;
 26 
 27 void prefixPrintGetValue(Solver& slv, Term t, int level = 0)
 28 {
 29   cout << "slv.getValue(" << t << "): " << slv.getValue(t) << endl;
 30 
 31   for (const Term& c : t)
 32   {
 33     prefixPrintGetValue(slv, c, level + 1);
 34   }
 35 }
 36 
 37 int main()
 38 {
 39   Solver slv;
 40   slv.setOption("produce-models", "true");  // Produce Models
 41   slv.setOption("dag-thresh", "0"); // Disable dagifying the output
 42   slv.setOption("output-language", "smt2"); // use smt-lib v2 as output language
 43   slv.setLogic(string("QF_UFLIRA"));
 44 
 45   // Sorts
 46   Sort u = slv.mkUninterpretedSort("u");
 47   Sort integer = slv.getIntegerSort();
 48   Sort boolean = slv.getBooleanSort();
 49   Sort uToInt = slv.mkFunctionSort({u}, integer);
 50   Sort intPred = slv.mkFunctionSort({integer}, boolean);
 51 
 52   // Variables
 53   Term x = slv.mkConst(u, "x");
 54   Term y = slv.mkConst(u, "y");
 55 
 56   // Functions
 57   Term f = slv.mkConst(uToInt, "f");
 58   Term p = slv.mkConst(intPred, "p");
 59 
 60   // Constants
 61   Term zero = slv.mkInteger(0);
 62   Term one = slv.mkInteger(1);
 63 
 64   // Terms
 65   Term f_x = slv.mkTerm(APPLY_UF, {f, x});
 66   Term f_y = slv.mkTerm(APPLY_UF, {f, y});
 67   Term sum = slv.mkTerm(ADD, {f_x, f_y});
 68   Term p_0 = slv.mkTerm(APPLY_UF, {p, zero});
 69   Term p_f_y = slv.mkTerm(APPLY_UF, {p, f_y});
 70 
 71   // Construct the assertions
 72   Term assertions =
 73       slv.mkTerm(AND,
 74                  {
 75                      slv.mkTerm(LEQ, {zero, f_x}),  // 0 <= f(x)
 76                      slv.mkTerm(LEQ, {zero, f_y}),  // 0 <= f(y)
 77                      slv.mkTerm(LEQ, {sum, one}),   // f(x) + f(y) <= 1
 78                      p_0.notTerm(),                 // not p(0)
 79                      p_f_y                          // p(f(y))
 80                  });
 81   slv.assertFormula(assertions);
 82 
 83   cout << "Given the following assertions:" << endl
 84        << assertions << endl << endl;
 85 
 86   cout << "Prove x /= y is entailed. " << endl
 87        << "cvc5: " << slv.checkSatAssuming(slv.mkTerm(EQUAL, {x, y})) << "."
 88        << endl
 89        << endl;
 90 
 91   cout << "Call checkSat to show that the assertions are satisfiable. "
 92        << endl
 93        << "cvc5: "
 94        << slv.checkSat() << "."<< endl << endl;
 95 
 96   cout << "Call slv.getValue(...) on terms of interest."
 97        << endl;
 98   cout << "slv.getValue(" << f_x << "): " << slv.getValue(f_x) << endl;
 99   cout << "slv.getValue(" << f_y << "): " << slv.getValue(f_y) << endl;
100   cout << "slv.getValue(" << sum << "): " << slv.getValue(sum) << endl;
101   cout << "slv.getValue(" << p_0 << "): " << slv.getValue(p_0) << endl;
102   cout << "slv.getValue(" << p_f_y << "): " << slv.getValue(p_f_y)
103        << endl << endl;
104 
105   cout << "Alternatively, iterate over assertions and call slv.getValue(...) "
106        << "on all terms."
107        << endl;
108   prefixPrintGetValue(slv, assertions);
109 
110   cout << endl;
111   cout << "You can also use nested loops to iterate over terms." << endl;
112   for (Term::const_iterator it = assertions.begin();
113        it != assertions.end();
114        ++it)
115   {
116     cout << "term: " << *it << endl;
117     for (Term::const_iterator it2 = (*it).begin();
118          it2 != (*it).end();
119          ++it2)
120     {
121       cout << " + child: " << *it2 << std::endl;
122     }
123   }
124   cout << endl;
125   cout << "Alternatively, you can also use for-each loops." << endl;
126   for (const Term& t : assertions)
127   {
128     cout << "term: " << t << endl;
129     for (const Term& c : t)
130     {
131       cout << " + child: " << c << endl;
132     }
133   }
134 
135   return 0;
136 }