SyGuS: Invariants

examples/api/cpp/sygus-inv.cpp

 1/******************************************************************************
 2 * This file is part of the cvc5 project.
 3 *
 4 * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
 5 * in the top-level source directory and their institutional affiliations.
 6 * All rights reserved.  See the file COPYING in the top-level source
 7 * directory for licensing information.
 8 * ****************************************************************************
 9 *
10 * A simple demonstration of the Sygus API.
11 *
12 * A simple demonstration of how to use the Sygus API to synthesize a simple
13 * invariant.
14 */
15
16#include <cvc5/cvc5.h>
17
18#include <iostream>
19
20#include "utils.h"
21
22using namespace cvc5;
23
24int main()
25{
26  TermManager tm;
27  Solver slv(tm);
28
29  // required options
30  slv.setOption("sygus", "true");
31  slv.setOption("incremental", "false");
32
33  // set the logic
34  slv.setLogic("LIA");
35
36  Sort integer = tm.getIntegerSort();
37  Sort boolean = tm.getBooleanSort();
38
39  Term zero = tm.mkInteger(0);
40  Term one = tm.mkInteger(1);
41  Term ten = tm.mkInteger(10);
42
43  // declare input variables for functions
44  Term x = tm.mkVar(integer, "x");
45  Term xp = tm.mkVar(integer, "xp");
46
47  // (ite (< x 10) (= xp (+ x 1)) (= xp x))
48  Term ite =
49      tm.mkTerm(Kind::ITE,
50                {tm.mkTerm(Kind::LT, {x, ten}),
51                 tm.mkTerm(Kind::EQUAL, {xp, tm.mkTerm(Kind::ADD, {x, one})}),
52                 tm.mkTerm(Kind::EQUAL, {xp, x})});
53
54  // define the pre-conditions, transition relations, and post-conditions
55  Term pre_f =
56      slv.defineFun("pre-f", {x}, boolean, tm.mkTerm(Kind::EQUAL, {x, zero}));
57  Term trans_f = slv.defineFun("trans-f", {x, xp}, boolean, ite);
58  Term post_f =
59      slv.defineFun("post-f", {x}, boolean, tm.mkTerm(Kind::LEQ, {x, ten}));
60
61  // declare the invariant-to-synthesize
62  Term inv_f = slv.synthFun("inv-f", {x}, boolean);
63
64  slv.addSygusInvConstraint(inv_f, pre_f, trans_f, post_f);
65
66  // print solutions if available
67  if (slv.checkSynth().hasSolution())
68  {
69    // Output should be equivalent to:
70    // (
71    //   (define-fun inv-f ((x Int)) Bool (not (>= x 11)))
72    // )
73    std::vector<Term> terms = {inv_f};
74    utils::printSynthSolutions(terms, slv.getSynthSolutions(terms));
75  }
76
77  return 0;
78}

The utility method used for printing the synthesis solutions in the examples above is defined separately in the utils module:

examples/api/cpp/utils.h

 1/******************************************************************************
 2 * This file is part of the cvc5 project.
 3 *
 4 * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
 5 * in the top-level source directory and their institutional affiliations.
 6 * All rights reserved.  See the file COPYING in the top-level source
 7 * directory for licensing information.
 8 * ****************************************************************************
 9 *
10 * Utility methods.
11 */
12
13#ifndef CVC5__UTILS_H
14#define CVC5__UTILS_H
15
16#include <cvc5/cvc5.h>
17
18namespace utils {
19
20/**
21 * Print solutions for synthesis conjecture to the standard output stream.
22 * @param terms the terms for which the synthesis solutions were retrieved
23 * @param sols the synthesis solutions of the given terms
24 */
25void printSynthSolutions(const std::vector<cvc5::Term>& terms,
26                         const std::vector<cvc5::Term>& sols);
27
28}  // namespace utils
29
30#endif  // CVC5__UTILS_H