File: sets.c

package info (click to toggle)
cvc5 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 87,260 kB
  • sloc: cpp: 383,850; java: 12,207; python: 12,090; sh: 5,679; ansic: 4,729; lisp: 763; perl: 208; makefile: 38
file content (136 lines) | stat: -rw-r--r-- 4,769 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/******************************************************************************
 * Top contributors (to current version):
 *   Aina Niemetz, Kshitij Bansal
 *
 * This file is part of the cvc5 project.
 *
 * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
 * in the top-level source directory and their institutional affiliations.
 * All rights reserved.  See the file COPYING in the top-level source
 * directory for licensing information.
 * ****************************************************************************
 *
 * A simple demonstration of reasoning about sets via the C API.
 */

#include <cvc5/c/cvc5.h>
#include <stdio.h>

int main()
{
  Cvc5TermManager* tm = cvc5_term_manager_new();
  Cvc5* slv = cvc5_new(tm);

  // Optionally, set the logic. We need at least UF for equality predicate,
  // integers (LIA) and sets (FS).
  cvc5_set_logic(slv, "QF_UFLIAFS");

  // Produce models
  cvc5_set_option(slv, "produce-models", "true");

  Cvc5Sort int_sort = cvc5_get_integer_sort(tm);
  Cvc5Sort set_sort = cvc5_mk_set_sort(tm, int_sort);

  // Verify union distributions over intersection
  // (A union B) intersection C = (A intersection C) union (B intersection C)
  {
    Cvc5Term A = cvc5_mk_const(tm, set_sort, "A");
    Cvc5Term B = cvc5_mk_const(tm, set_sort, "B");
    Cvc5Term C = cvc5_mk_const(tm, set_sort, "C");

    Cvc5Term args2[2] = {A, B};
    Cvc5Term union_AB = cvc5_mk_term(tm, CVC5_KIND_SET_UNION, 2, args2);
    args2[0] = union_AB;
    args2[1] = C;
    Cvc5Term lhs = cvc5_mk_term(tm, CVC5_KIND_SET_INTER, 2, args2);

    args2[0] = A;
    args2[1] = C;
    Cvc5Term inter_AC = cvc5_mk_term(tm, CVC5_KIND_SET_INTER, 2, args2);
    args2[0] = B;
    args2[1] = C;
    Cvc5Term inter_BC = cvc5_mk_term(tm, CVC5_KIND_SET_INTER, 2, args2);
    args2[0] = inter_AC;
    args2[1] = inter_BC;
    Cvc5Term rhs = cvc5_mk_term(tm, CVC5_KIND_SET_UNION, 2, args2);

    args2[0] = lhs;
    args2[1] = rhs;
    Cvc5Term theorem = cvc5_mk_term(tm, CVC5_KIND_EQUAL, 2, args2);

    Cvc5Term args1[1] = {theorem};
    Cvc5Term assumptions[1] = {cvc5_mk_term(tm, CVC5_KIND_NOT, 1, args1)};
    printf("cvc5 reports: %s is %s.\n",
           cvc5_term_to_string(theorem),
           cvc5_result_to_string(cvc5_check_sat_assuming(slv, 1, assumptions)));
    // optional, not needed anymore so we can release
    cvc5_term_release(A);
    cvc5_term_release(B);
    cvc5_term_release(C);
    cvc5_term_release(union_AB);
    cvc5_term_release(inter_AC);
    cvc5_term_release(inter_BC);
    cvc5_term_release(lhs);
    cvc5_term_release(rhs);
    cvc5_term_release(theorem);
  }

  // Verify emptset is a subset of any set
  {
    Cvc5Term A = cvc5_mk_const(tm, set_sort, "A");
    Cvc5Term empty_set = cvc5_mk_empty_set(tm, set_sort);

    Cvc5Term args2[2] = {empty_set, A};
    Cvc5Term theorem = cvc5_mk_term(tm, CVC5_KIND_SET_SUBSET, 2, args2);

    Cvc5Term args1[1] = {theorem};
    Cvc5Term assumptions[1] = {cvc5_mk_term(tm, CVC5_KIND_NOT, 1, args1)};
    printf("cvc5 reports: %s is %s.\n",
           cvc5_term_to_string(theorem),
           cvc5_result_to_string(cvc5_check_sat_assuming(slv, 1, assumptions)));
    // optional, not needed anymore so we can release
    cvc5_term_release(A);
    cvc5_term_release(theorem);
  }

  // Find me an element in {1, 2} intersection {2, 3}, if there is one.
  {
    Cvc5Term one = cvc5_mk_integer_int64(tm, 1);
    Cvc5Term two = cvc5_mk_integer_int64(tm, 2);
    Cvc5Term three = cvc5_mk_integer_int64(tm, 3);

    Cvc5Term args1[1] = {one};
    Cvc5Term sing_one = cvc5_mk_term(tm, CVC5_KIND_SET_SINGLETON, 1, args1);
    args1[0] = two;
    Cvc5Term sing_two = cvc5_mk_term(tm, CVC5_KIND_SET_SINGLETON, 1, args1);
    args1[0] = three;
    Cvc5Term sing_three = cvc5_mk_term(tm, CVC5_KIND_SET_SINGLETON, 1, args1);
    Cvc5Term args2[2] = {sing_one, sing_two};
    Cvc5Term one_two = cvc5_mk_term(tm, CVC5_KIND_SET_UNION, 2, args2);
    args2[0] = sing_two;
    args2[1] = sing_three;
    Cvc5Term two_three = cvc5_mk_term(tm, CVC5_KIND_SET_UNION, 2, args2);
    args2[0] = one_two;
    args2[1] = two_three;
    Cvc5Term inter = cvc5_mk_term(tm, CVC5_KIND_SET_INTER, 2, args2);

    Cvc5Term x = cvc5_mk_const(tm, int_sort, "x");
    args2[0] = x;
    args2[1] = inter;
    Cvc5Term e = cvc5_mk_term(tm, CVC5_KIND_SET_MEMBER, 2, args2);

    Cvc5Term assumptions[1] = {e};
    Cvc5Result result = cvc5_check_sat_assuming(slv, 1, assumptions);
    printf("cvc5 reports: %s is %s.\n",
           cvc5_term_to_string(e),
           cvc5_result_to_string(result));

    if (cvc5_result_is_sat(result))
    {
      printf("For instance, %s is a member.\n",
             cvc5_term_to_string(cvc5_get_value(slv, x)));
    }
  }
  cvc5_delete(slv);
  cvc5_term_manager_delete(tm);
}