Theory Combination

examples/api/cpp/combination.cpp

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