SyGuS: Functions

examples/api/cpp/sygus-fun.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 max and min
 13 * functions.
 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  // declare input variables for the functions-to-synthesize
 40  Term x = tm.mkVar(integer, "x");
 41  Term y = tm.mkVar(integer, "y");
 42
 43  // declare the grammar non-terminals
 44  Term start = tm.mkVar(integer, "Start");
 45  Term start_bool = tm.mkVar(boolean, "StartBool");
 46
 47  // define the rules
 48  Term zero = tm.mkInteger(0);
 49  Term one = tm.mkInteger(1);
 50
 51  Term plus = tm.mkTerm(Kind::ADD, {start, start});
 52  Term minus = tm.mkTerm(Kind::SUB, {start, start});
 53  Term ite = tm.mkTerm(Kind::ITE, {start_bool, start, start});
 54
 55  Term And = tm.mkTerm(Kind::AND, {start_bool, start_bool});
 56  Term Not = tm.mkTerm(Kind::NOT, {start_bool});
 57  Term leq = tm.mkTerm(Kind::LEQ, {start, start});
 58
 59  // create the grammar object
 60  Grammar g = slv.mkGrammar({x, y}, {start, start_bool});
 61
 62  // bind each non-terminal to its rules
 63  g.addRules(start, {zero, one, x, y, plus, minus, ite});
 64  g.addRules(start_bool, {And, Not, leq});
 65
 66  // declare the functions-to-synthesize. Optionally, provide the grammar
 67  // constraints
 68  Term max = slv.synthFun("max", {x, y}, integer, g);
 69  Term min = slv.synthFun("min", {x, y}, integer);
 70
 71  // declare universal variables.
 72  Term varX = slv.declareSygusVar("x", integer);
 73  Term varY = slv.declareSygusVar("y", integer);
 74
 75  Term max_x_y = tm.mkTerm(Kind::APPLY_UF, {max, varX, varY});
 76  Term min_x_y = tm.mkTerm(Kind::APPLY_UF, {min, varX, varY});
 77
 78  // add semantic constraints
 79  // (constraint (>= (max x y) x))
 80  slv.addSygusConstraint(tm.mkTerm(Kind::GEQ, {max_x_y, varX}));
 81
 82  // (constraint (>= (max x y) y))
 83  slv.addSygusConstraint(tm.mkTerm(Kind::GEQ, {max_x_y, varY}));
 84
 85  // (constraint (or (= x (max x y))
 86  //                 (= y (max x y))))
 87  slv.addSygusConstraint(tm.mkTerm(Kind::OR,
 88                                   {tm.mkTerm(Kind::EQUAL, {max_x_y, varX}),
 89                                    tm.mkTerm(Kind::EQUAL, {max_x_y, varY})}));
 90
 91  // (constraint (= (+ (max x y) (min x y))
 92  //                (+ x y)))
 93  slv.addSygusConstraint(tm.mkTerm(Kind::EQUAL,
 94                                   {tm.mkTerm(Kind::ADD, {max_x_y, min_x_y}),
 95                                    tm.mkTerm(Kind::ADD, {varX, varY})}));
 96
 97  // print solutions if available
 98  if (slv.checkSynth().hasSolution())
 99  {
100    // Output should be equivalent to:
101    // (
102    //   (define-fun max ((x Int) (y Int)) Int (ite (<= x y) y x))
103    //   (define-fun min ((x Int) (y Int)) Int (ite (<= x y) x y))
104    // )
105    std::vector<Term> terms = {max, min};
106    utils::printSynthSolutions(terms, slv.getSynthSolutions(terms));
107  }
108
109  return 0;
110}

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