Theory of Strings

examples/api/cpp/strings.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 reasoning about strings via the C++ API.
11 */
12
13#include <cvc5/cvc5.h>
14
15#include <iostream>
16
17using namespace cvc5;
18
19int main()
20{
21  TermManager tm;
22  Solver slv(tm);
23
24  // Set the logic
25  slv.setLogic("QF_SLIA");
26  // Produce models
27  slv.setOption("produce-models", "true");
28  // The option strings-exp is needed
29  slv.setOption("strings-exp", "true");
30
31  // String type
32  Sort string = tm.getStringSort();
33
34  // std::string
35  std::string str_ab("ab");
36  // String constants
37  Term ab = tm.mkString(str_ab);
38  Term abc = tm.mkString("abc");
39  // String variables
40  Term x = tm.mkConst(string, "x");
41  Term y = tm.mkConst(string, "y");
42  Term z = tm.mkConst(string, "z");
43
44  // String concatenation: x.ab.y
45  Term lhs = tm.mkTerm(Kind::STRING_CONCAT, {x, ab, y});
46  // String concatenation: abc.z
47  Term rhs = tm.mkTerm(Kind::STRING_CONCAT, {abc, z});
48  // x.ab.y = abc.z
49  Term formula1 = tm.mkTerm(Kind::EQUAL, {lhs, rhs});
50
51  // Length of y: |y|
52  Term leny = tm.mkTerm(Kind::STRING_LENGTH, {y});
53  // |y| >= 0
54  Term formula2 = tm.mkTerm(Kind::GEQ, {leny, tm.mkInteger(0)});
55
56  // Regular expression: (ab[c-e]*f)|g|h
57  Term r = tm.mkTerm(
58      Kind::REGEXP_UNION,
59
60      {tm.mkTerm(Kind::REGEXP_CONCAT,
61                 {tm.mkTerm(Kind::STRING_TO_REGEXP, {tm.mkString("ab")}),
62                  tm.mkTerm(Kind::REGEXP_STAR,
63                            {tm.mkTerm(Kind::REGEXP_RANGE,
64                                       {tm.mkString("c"), tm.mkString("e")})}),
65                  tm.mkTerm(Kind::STRING_TO_REGEXP, {tm.mkString("f")})}),
66       tm.mkTerm(Kind::STRING_TO_REGEXP, {tm.mkString("g")}),
67       tm.mkTerm(Kind::STRING_TO_REGEXP, {tm.mkString("h")})});
68
69  // String variables
70  Term s1 = tm.mkConst(string, "s1");
71  Term s2 = tm.mkConst(string, "s2");
72  // String concatenation: s1.s2
73  Term s = tm.mkTerm(Kind::STRING_CONCAT, {s1, s2});
74
75  // s1.s2 in (ab[c-e]*f)|g|h
76  Term formula3 = tm.mkTerm(Kind::STRING_IN_REGEXP, {s, r});
77
78  // Make a query
79  Term q = tm.mkTerm(Kind::AND, {formula1, formula2, formula3});
80
81  // check sat
82  Result result = slv.checkSatAssuming(q);
83  std::cout << "cvc5 reports: " << q << " is " << result << "." << std::endl;
84
85  if(result.isSat())
86  {
87    std::cout << "  x  = " << slv.getValue(x) << std::endl;
88    std::cout << "  s1.s2 = " << slv.getValue(s) << std::endl;
89  }
90}