1c9666d23SWei Yi Tee //===- unittests/Analysis/FlowSensitive/DebugSupportTest.cpp --------------===//
2c9666d23SWei Yi Tee //
3c9666d23SWei Yi Tee // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c9666d23SWei Yi Tee // See https://llvm.org/LICENSE.txt for license information.
5c9666d23SWei Yi Tee // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c9666d23SWei Yi Tee //
7c9666d23SWei Yi Tee //===----------------------------------------------------------------------===//
8c9666d23SWei Yi Tee
9c9666d23SWei Yi Tee #include "clang/Analysis/FlowSensitive/DebugSupport.h"
10c9666d23SWei Yi Tee #include "TestingSupport.h"
11c9666d23SWei Yi Tee #include "clang/Analysis/FlowSensitive/Value.h"
12b8d83e80SWei Yi Tee #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
13c9666d23SWei Yi Tee #include "gmock/gmock.h"
14c9666d23SWei Yi Tee #include "gtest/gtest.h"
15c9666d23SWei Yi Tee
16c9666d23SWei Yi Tee namespace {
17c9666d23SWei Yi Tee
18c9666d23SWei Yi Tee using namespace clang;
19c9666d23SWei Yi Tee using namespace dataflow;
20c9666d23SWei Yi Tee
21c9666d23SWei Yi Tee using test::ConstraintContext;
22c9666d23SWei Yi Tee using testing::StrEq;
23c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,AtomicBoolean)24c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, AtomicBoolean) {
25c9666d23SWei Yi Tee // B0
26c9666d23SWei Yi Tee ConstraintContext Ctx;
27c9666d23SWei Yi Tee auto B = Ctx.atom();
28c9666d23SWei Yi Tee
29c9666d23SWei Yi Tee auto Expected = R"(B0)";
30c9666d23SWei Yi Tee debugString(*B);
31c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
32c9666d23SWei Yi Tee }
33c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Negation)34c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Negation) {
35c9666d23SWei Yi Tee // !B0
36c9666d23SWei Yi Tee ConstraintContext Ctx;
37c9666d23SWei Yi Tee auto B = Ctx.neg(Ctx.atom());
38c9666d23SWei Yi Tee
39c9666d23SWei Yi Tee auto Expected = R"((not
40c9666d23SWei Yi Tee B0))";
41c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
42c9666d23SWei Yi Tee }
43c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Conjunction)44c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Conjunction) {
45c9666d23SWei Yi Tee // B0 ^ B1
46c9666d23SWei Yi Tee ConstraintContext Ctx;
47c9666d23SWei Yi Tee auto B = Ctx.conj(Ctx.atom(), Ctx.atom());
48c9666d23SWei Yi Tee
49c9666d23SWei Yi Tee auto Expected = R"((and
50c9666d23SWei Yi Tee B0
51c9666d23SWei Yi Tee B1))";
52c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
53c9666d23SWei Yi Tee }
54c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Disjunction)55c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Disjunction) {
56c9666d23SWei Yi Tee // B0 v B1
57c9666d23SWei Yi Tee ConstraintContext Ctx;
58c9666d23SWei Yi Tee auto B = Ctx.disj(Ctx.atom(), Ctx.atom());
59c9666d23SWei Yi Tee
60c9666d23SWei Yi Tee auto Expected = R"((or
61c9666d23SWei Yi Tee B0
62c9666d23SWei Yi Tee B1))";
63c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
64c9666d23SWei Yi Tee }
65c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Implication)66c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Implication) {
67*b5e3dac3SDmitri Gribenko // B0 => B1
68c9666d23SWei Yi Tee ConstraintContext Ctx;
69*b5e3dac3SDmitri Gribenko auto B = Ctx.impl(Ctx.atom(), Ctx.atom());
70c9666d23SWei Yi Tee
71*b5e3dac3SDmitri Gribenko auto Expected = R"((=>
72*b5e3dac3SDmitri Gribenko B0
73c9666d23SWei Yi Tee B1))";
74c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
75c9666d23SWei Yi Tee }
76c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Iff)77c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Iff) {
78*b5e3dac3SDmitri Gribenko // B0 <=> B1
79c9666d23SWei Yi Tee ConstraintContext Ctx;
80*b5e3dac3SDmitri Gribenko auto B = Ctx.iff(Ctx.atom(), Ctx.atom());
81c9666d23SWei Yi Tee
82*b5e3dac3SDmitri Gribenko auto Expected = R"((=
83c9666d23SWei Yi Tee B0
84*b5e3dac3SDmitri Gribenko B1))";
85c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
86c9666d23SWei Yi Tee }
87c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,Xor)88c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, Xor) {
89c9666d23SWei Yi Tee // (B0 ^ !B1) V (!B0 ^ B1)
90c9666d23SWei Yi Tee ConstraintContext Ctx;
91c9666d23SWei Yi Tee auto B0 = Ctx.atom();
92c9666d23SWei Yi Tee auto B1 = Ctx.atom();
93c9666d23SWei Yi Tee auto B = Ctx.disj(Ctx.conj(B0, Ctx.neg(B1)), Ctx.conj(Ctx.neg(B0), B1));
94c9666d23SWei Yi Tee
95c9666d23SWei Yi Tee auto Expected = R"((or
96c9666d23SWei Yi Tee (and
97c9666d23SWei Yi Tee B0
98c9666d23SWei Yi Tee (not
99c9666d23SWei Yi Tee B1))
100c9666d23SWei Yi Tee (and
101c9666d23SWei Yi Tee (not
102c9666d23SWei Yi Tee B0)
103c9666d23SWei Yi Tee B1)))";
104c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
105c9666d23SWei Yi Tee }
106c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,NestedBoolean)107c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, NestedBoolean) {
108c9666d23SWei Yi Tee // B0 ^ (B1 v (B2 ^ (B3 v B4)))
109c9666d23SWei Yi Tee ConstraintContext Ctx;
110c9666d23SWei Yi Tee auto B = Ctx.conj(
111c9666d23SWei Yi Tee Ctx.atom(),
112c9666d23SWei Yi Tee Ctx.disj(Ctx.atom(),
113c9666d23SWei Yi Tee Ctx.conj(Ctx.atom(), Ctx.disj(Ctx.atom(), Ctx.atom()))));
114c9666d23SWei Yi Tee
115c9666d23SWei Yi Tee auto Expected = R"((and
116c9666d23SWei Yi Tee B0
117c9666d23SWei Yi Tee (or
118c9666d23SWei Yi Tee B1
119c9666d23SWei Yi Tee (and
120c9666d23SWei Yi Tee B2
121c9666d23SWei Yi Tee (or
122c9666d23SWei Yi Tee B3
123c9666d23SWei Yi Tee B4)))))";
124c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B), StrEq(Expected));
125c9666d23SWei Yi Tee }
126c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,AtomicBooleanWithName)127c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, AtomicBooleanWithName) {
128c9666d23SWei Yi Tee // True
129c9666d23SWei Yi Tee ConstraintContext Ctx;
130c9666d23SWei Yi Tee auto True = cast<AtomicBoolValue>(Ctx.atom());
131c9666d23SWei Yi Tee auto B = True;
132c9666d23SWei Yi Tee
133c9666d23SWei Yi Tee auto Expected = R"(True)";
134c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B, {{True, "True"}}), StrEq(Expected));
135c9666d23SWei Yi Tee }
136c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,ComplexBooleanWithNames)137c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, ComplexBooleanWithNames) {
138c9666d23SWei Yi Tee // (Cond ^ Then ^ !Else) v (!Cond ^ !Then ^ Else)
139c9666d23SWei Yi Tee ConstraintContext Ctx;
140c9666d23SWei Yi Tee auto Cond = cast<AtomicBoolValue>(Ctx.atom());
141c9666d23SWei Yi Tee auto Then = cast<AtomicBoolValue>(Ctx.atom());
142c9666d23SWei Yi Tee auto Else = cast<AtomicBoolValue>(Ctx.atom());
143c9666d23SWei Yi Tee auto B = Ctx.disj(Ctx.conj(Cond, Ctx.conj(Then, Ctx.neg(Else))),
144c9666d23SWei Yi Tee Ctx.conj(Ctx.neg(Cond), Ctx.conj(Ctx.neg(Then), Else)));
145c9666d23SWei Yi Tee
146c9666d23SWei Yi Tee auto Expected = R"((or
147c9666d23SWei Yi Tee (and
148c9666d23SWei Yi Tee Cond
149c9666d23SWei Yi Tee (and
150c9666d23SWei Yi Tee Then
151c9666d23SWei Yi Tee (not
152c9666d23SWei Yi Tee Else)))
153c9666d23SWei Yi Tee (and
154c9666d23SWei Yi Tee (not
155c9666d23SWei Yi Tee Cond)
156c9666d23SWei Yi Tee (and
157c9666d23SWei Yi Tee (not
158c9666d23SWei Yi Tee Then)
159c9666d23SWei Yi Tee Else))))";
160c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B, {{Cond, "Cond"}, {Then, "Then"}, {Else, "Else"}}),
161c9666d23SWei Yi Tee StrEq(Expected));
162c9666d23SWei Yi Tee }
163c9666d23SWei Yi Tee
TEST(BoolValueDebugStringTest,ComplexBooleanWithSomeNames)164c9666d23SWei Yi Tee TEST(BoolValueDebugStringTest, ComplexBooleanWithSomeNames) {
165c9666d23SWei Yi Tee // (False && B0) v (True v B1)
166c9666d23SWei Yi Tee ConstraintContext Ctx;
167c9666d23SWei Yi Tee auto True = cast<AtomicBoolValue>(Ctx.atom());
168c9666d23SWei Yi Tee auto False = cast<AtomicBoolValue>(Ctx.atom());
169c9666d23SWei Yi Tee auto B = Ctx.disj(Ctx.conj(False, Ctx.atom()), Ctx.disj(True, Ctx.atom()));
170c9666d23SWei Yi Tee
171c9666d23SWei Yi Tee auto Expected = R"((or
172c9666d23SWei Yi Tee (and
173c9666d23SWei Yi Tee False
174c9666d23SWei Yi Tee B0)
175c9666d23SWei Yi Tee (or
176c9666d23SWei Yi Tee True
177c9666d23SWei Yi Tee B1)))";
178c9666d23SWei Yi Tee EXPECT_THAT(debugString(*B, {{True, "True"}, {False, "False"}}),
179c9666d23SWei Yi Tee StrEq(Expected));
180c9666d23SWei Yi Tee }
181c9666d23SWei Yi Tee
TEST(ConstraintSetDebugStringTest,Empty)182b5414b56SDmitri Gribenko TEST(ConstraintSetDebugStringTest, Empty) {
183b5414b56SDmitri Gribenko llvm::DenseSet<BoolValue *> Constraints;
184b5414b56SDmitri Gribenko EXPECT_THAT(debugString(Constraints), StrEq(""));
185b5414b56SDmitri Gribenko }
186b5414b56SDmitri Gribenko
TEST(ConstraintSetDebugStringTest,Simple)187b5414b56SDmitri Gribenko TEST(ConstraintSetDebugStringTest, Simple) {
188b5414b56SDmitri Gribenko ConstraintContext Ctx;
189b5414b56SDmitri Gribenko llvm::DenseSet<BoolValue *> Constraints;
190b5414b56SDmitri Gribenko auto X = cast<AtomicBoolValue>(Ctx.atom());
191b5414b56SDmitri Gribenko auto Y = cast<AtomicBoolValue>(Ctx.atom());
192b5414b56SDmitri Gribenko Constraints.insert(Ctx.disj(X, Y));
193b5414b56SDmitri Gribenko Constraints.insert(Ctx.disj(X, Ctx.neg(Y)));
194b5414b56SDmitri Gribenko
195b5414b56SDmitri Gribenko auto Expected = R"((or
196b5414b56SDmitri Gribenko X
197b5414b56SDmitri Gribenko (not
198b5414b56SDmitri Gribenko Y))
199b5414b56SDmitri Gribenko (or
200b5414b56SDmitri Gribenko X
201b5414b56SDmitri Gribenko Y)
202b5414b56SDmitri Gribenko )";
203b5414b56SDmitri Gribenko EXPECT_THAT(debugString(Constraints, {{X, "X"}, {Y, "Y"}}),
204b5414b56SDmitri Gribenko StrEq(Expected));
205b5414b56SDmitri Gribenko }
206b5414b56SDmitri Gribenko
CheckSAT(std::vector<BoolValue * > Constraints)207b8d83e80SWei Yi Tee Solver::Result CheckSAT(std::vector<BoolValue *> Constraints) {
208b8d83e80SWei Yi Tee llvm::DenseSet<BoolValue *> ConstraintsSet(Constraints.begin(),
209b8d83e80SWei Yi Tee Constraints.end());
210b8d83e80SWei Yi Tee return WatchedLiteralsSolver().solve(std::move(ConstraintsSet));
211b8d83e80SWei Yi Tee }
212b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,AtomicBoolean)213b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, AtomicBoolean) {
214b8d83e80SWei Yi Tee // B0
215b8d83e80SWei Yi Tee ConstraintContext Ctx;
216b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({Ctx.atom()});
217b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
218b8d83e80SWei Yi Tee
219b8d83e80SWei Yi Tee auto Expected = R"(
220b8d83e80SWei Yi Tee Constraints
221b8d83e80SWei Yi Tee ------------
222b8d83e80SWei Yi Tee B0
223b8d83e80SWei Yi Tee ------------
224b8d83e80SWei Yi Tee Satisfiable.
225b8d83e80SWei Yi Tee
226b8d83e80SWei Yi Tee B0 = True
227b8d83e80SWei Yi Tee )";
228b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
229b8d83e80SWei Yi Tee }
230b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,AtomicBooleanAndNegation)231b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, AtomicBooleanAndNegation) {
232b8d83e80SWei Yi Tee // B0, !B0
233b8d83e80SWei Yi Tee ConstraintContext Ctx;
234b8d83e80SWei Yi Tee auto B0 = Ctx.atom();
235b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({B0, Ctx.neg(B0)});
236b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
237b8d83e80SWei Yi Tee
238b8d83e80SWei Yi Tee auto Expected = R"(
239b8d83e80SWei Yi Tee Constraints
240b8d83e80SWei Yi Tee ------------
241b8d83e80SWei Yi Tee B0
242b8d83e80SWei Yi Tee
243b8d83e80SWei Yi Tee (not
244b8d83e80SWei Yi Tee B0)
245b8d83e80SWei Yi Tee ------------
246b8d83e80SWei Yi Tee Unsatisfiable.
247b8d83e80SWei Yi Tee
248b8d83e80SWei Yi Tee )";
249b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
250b8d83e80SWei Yi Tee }
251b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,MultipleAtomicBooleans)252b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, MultipleAtomicBooleans) {
253b8d83e80SWei Yi Tee // B0, B1
254b8d83e80SWei Yi Tee ConstraintContext Ctx;
255b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({Ctx.atom(), Ctx.atom()});
256b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
257b8d83e80SWei Yi Tee
258b8d83e80SWei Yi Tee auto Expected = R"(
259b8d83e80SWei Yi Tee Constraints
260b8d83e80SWei Yi Tee ------------
261b8d83e80SWei Yi Tee B0
262b8d83e80SWei Yi Tee
263b8d83e80SWei Yi Tee B1
264b8d83e80SWei Yi Tee ------------
265b8d83e80SWei Yi Tee Satisfiable.
266b8d83e80SWei Yi Tee
267b8d83e80SWei Yi Tee B0 = True
268b8d83e80SWei Yi Tee B1 = True
269b8d83e80SWei Yi Tee )";
270b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
271b8d83e80SWei Yi Tee }
272b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,Implication)273b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, Implication) {
274b8d83e80SWei Yi Tee // B0, B0 => B1
275b8d83e80SWei Yi Tee ConstraintContext Ctx;
276b8d83e80SWei Yi Tee auto B0 = Ctx.atom();
277b8d83e80SWei Yi Tee auto B1 = Ctx.atom();
278b8d83e80SWei Yi Tee auto Impl = Ctx.disj(Ctx.neg(B0), B1);
279b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({B0, Impl});
280b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
281b8d83e80SWei Yi Tee
282b8d83e80SWei Yi Tee auto Expected = R"(
283b8d83e80SWei Yi Tee Constraints
284b8d83e80SWei Yi Tee ------------
285b8d83e80SWei Yi Tee B0
286b8d83e80SWei Yi Tee
287b8d83e80SWei Yi Tee (or
288b8d83e80SWei Yi Tee (not
289b8d83e80SWei Yi Tee B0)
290b8d83e80SWei Yi Tee B1)
291b8d83e80SWei Yi Tee ------------
292b8d83e80SWei Yi Tee Satisfiable.
293b8d83e80SWei Yi Tee
294b8d83e80SWei Yi Tee B0 = True
295b8d83e80SWei Yi Tee B1 = True
296b8d83e80SWei Yi Tee )";
297b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
298b8d83e80SWei Yi Tee }
299b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,Iff)300b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, Iff) {
301b8d83e80SWei Yi Tee // B0, B0 <=> B1
302b8d83e80SWei Yi Tee ConstraintContext Ctx;
303b8d83e80SWei Yi Tee auto B0 = Ctx.atom();
304b8d83e80SWei Yi Tee auto B1 = Ctx.atom();
305b8d83e80SWei Yi Tee auto Iff = Ctx.conj(Ctx.disj(Ctx.neg(B0), B1), Ctx.disj(B0, Ctx.neg(B1)));
306b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({B0, Iff});
307b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
308b8d83e80SWei Yi Tee
309b8d83e80SWei Yi Tee auto Expected = R"(
310b8d83e80SWei Yi Tee Constraints
311b8d83e80SWei Yi Tee ------------
312b8d83e80SWei Yi Tee B0
313b8d83e80SWei Yi Tee
314b8d83e80SWei Yi Tee (and
315b8d83e80SWei Yi Tee (or
316b8d83e80SWei Yi Tee (not
317b8d83e80SWei Yi Tee B0)
318b8d83e80SWei Yi Tee B1)
319b8d83e80SWei Yi Tee (or
320b8d83e80SWei Yi Tee B0
321b8d83e80SWei Yi Tee (not
322b8d83e80SWei Yi Tee B1)))
323b8d83e80SWei Yi Tee ------------
324b8d83e80SWei Yi Tee Satisfiable.
325b8d83e80SWei Yi Tee
326b8d83e80SWei Yi Tee B0 = True
327b8d83e80SWei Yi Tee B1 = True
328b8d83e80SWei Yi Tee )";
329b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
330b8d83e80SWei Yi Tee }
331b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,Xor)332b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, Xor) {
333b8d83e80SWei Yi Tee // B0, XOR(B0, B1)
334b8d83e80SWei Yi Tee ConstraintContext Ctx;
335b8d83e80SWei Yi Tee auto B0 = Ctx.atom();
336b8d83e80SWei Yi Tee auto B1 = Ctx.atom();
337b8d83e80SWei Yi Tee auto XOR = Ctx.disj(Ctx.conj(B0, Ctx.neg(B1)), Ctx.conj(Ctx.neg(B0), B1));
338b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({B0, XOR});
339b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
340b8d83e80SWei Yi Tee
341b8d83e80SWei Yi Tee auto Expected = R"(
342b8d83e80SWei Yi Tee Constraints
343b8d83e80SWei Yi Tee ------------
344b8d83e80SWei Yi Tee B0
345b8d83e80SWei Yi Tee
346b8d83e80SWei Yi Tee (or
347b8d83e80SWei Yi Tee (and
348b8d83e80SWei Yi Tee B0
349b8d83e80SWei Yi Tee (not
350b8d83e80SWei Yi Tee B1))
351b8d83e80SWei Yi Tee (and
352b8d83e80SWei Yi Tee (not
353b8d83e80SWei Yi Tee B0)
354b8d83e80SWei Yi Tee B1))
355b8d83e80SWei Yi Tee ------------
356b8d83e80SWei Yi Tee Satisfiable.
357b8d83e80SWei Yi Tee
358b8d83e80SWei Yi Tee B0 = True
359b8d83e80SWei Yi Tee B1 = False
360b8d83e80SWei Yi Tee )";
361b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result), StrEq(Expected));
362b8d83e80SWei Yi Tee }
363b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,ComplexBooleanWithNames)364b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, ComplexBooleanWithNames) {
365b8d83e80SWei Yi Tee // Cond, (Cond ^ Then ^ !Else) v (!Cond ^ !Then ^ Else)
366b8d83e80SWei Yi Tee ConstraintContext Ctx;
367b8d83e80SWei Yi Tee auto Cond = cast<AtomicBoolValue>(Ctx.atom());
368b8d83e80SWei Yi Tee auto Then = cast<AtomicBoolValue>(Ctx.atom());
369b8d83e80SWei Yi Tee auto Else = cast<AtomicBoolValue>(Ctx.atom());
370b8d83e80SWei Yi Tee auto B = Ctx.disj(Ctx.conj(Cond, Ctx.conj(Then, Ctx.neg(Else))),
371b8d83e80SWei Yi Tee Ctx.conj(Ctx.neg(Cond), Ctx.conj(Ctx.neg(Then), Else)));
372b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints({Cond, B});
373b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
374b8d83e80SWei Yi Tee
375b8d83e80SWei Yi Tee auto Expected = R"(
376b8d83e80SWei Yi Tee Constraints
377b8d83e80SWei Yi Tee ------------
378b8d83e80SWei Yi Tee Cond
379b8d83e80SWei Yi Tee
380b8d83e80SWei Yi Tee (or
381b8d83e80SWei Yi Tee (and
382b8d83e80SWei Yi Tee Cond
383b8d83e80SWei Yi Tee (and
384b8d83e80SWei Yi Tee Then
385b8d83e80SWei Yi Tee (not
386b8d83e80SWei Yi Tee Else)))
387b8d83e80SWei Yi Tee (and
388b8d83e80SWei Yi Tee (not
389b8d83e80SWei Yi Tee Cond)
390b8d83e80SWei Yi Tee (and
391b8d83e80SWei Yi Tee (not
392b8d83e80SWei Yi Tee Then)
393b8d83e80SWei Yi Tee Else)))
394b8d83e80SWei Yi Tee ------------
395b8d83e80SWei Yi Tee Satisfiable.
396b8d83e80SWei Yi Tee
397b8d83e80SWei Yi Tee Cond = True
398b8d83e80SWei Yi Tee Else = False
399b8d83e80SWei Yi Tee Then = True
400b8d83e80SWei Yi Tee )";
401b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result,
402b8d83e80SWei Yi Tee {{Cond, "Cond"}, {Then, "Then"}, {Else, "Else"}}),
403b8d83e80SWei Yi Tee StrEq(Expected));
404b8d83e80SWei Yi Tee }
405b8d83e80SWei Yi Tee
TEST(SATCheckDebugStringTest,ComplexBooleanWithLongNames)406b8d83e80SWei Yi Tee TEST(SATCheckDebugStringTest, ComplexBooleanWithLongNames) {
407b8d83e80SWei Yi Tee // ThisIntEqZero, !IntsAreEq, ThisIntEqZero ^ OtherIntEqZero => IntsAreEq
408b8d83e80SWei Yi Tee ConstraintContext Ctx;
409b8d83e80SWei Yi Tee auto IntsAreEq = cast<AtomicBoolValue>(Ctx.atom());
410b8d83e80SWei Yi Tee auto ThisIntEqZero = cast<AtomicBoolValue>(Ctx.atom());
411b8d83e80SWei Yi Tee auto OtherIntEqZero = cast<AtomicBoolValue>(Ctx.atom());
412b8d83e80SWei Yi Tee auto BothZeroImpliesEQ =
413b8d83e80SWei Yi Tee Ctx.disj(Ctx.neg(Ctx.conj(ThisIntEqZero, OtherIntEqZero)), IntsAreEq);
414b8d83e80SWei Yi Tee std::vector<BoolValue *> Constraints(
415b8d83e80SWei Yi Tee {ThisIntEqZero, Ctx.neg(IntsAreEq), BothZeroImpliesEQ});
416b8d83e80SWei Yi Tee auto Result = CheckSAT(Constraints);
417b8d83e80SWei Yi Tee
418b8d83e80SWei Yi Tee auto Expected = R"(
419b8d83e80SWei Yi Tee Constraints
420b8d83e80SWei Yi Tee ------------
421b8d83e80SWei Yi Tee ThisIntEqZero
422b8d83e80SWei Yi Tee
423b8d83e80SWei Yi Tee (not
424b8d83e80SWei Yi Tee IntsAreEq)
425b8d83e80SWei Yi Tee
426b8d83e80SWei Yi Tee (or
427b8d83e80SWei Yi Tee (not
428b8d83e80SWei Yi Tee (and
429b8d83e80SWei Yi Tee ThisIntEqZero
430b8d83e80SWei Yi Tee OtherIntEqZero))
431b8d83e80SWei Yi Tee IntsAreEq)
432b8d83e80SWei Yi Tee ------------
433b8d83e80SWei Yi Tee Satisfiable.
434b8d83e80SWei Yi Tee
435b8d83e80SWei Yi Tee IntsAreEq = False
436b8d83e80SWei Yi Tee OtherIntEqZero = False
437b8d83e80SWei Yi Tee ThisIntEqZero = True
438b8d83e80SWei Yi Tee )";
439b8d83e80SWei Yi Tee EXPECT_THAT(debugString(Constraints, Result,
440b8d83e80SWei Yi Tee {{IntsAreEq, "IntsAreEq"},
441b8d83e80SWei Yi Tee {ThisIntEqZero, "ThisIntEqZero"},
442b8d83e80SWei Yi Tee {OtherIntEqZero, "OtherIntEqZero"}}),
443b8d83e80SWei Yi Tee StrEq(Expected));
444b8d83e80SWei Yi Tee }
445c9666d23SWei Yi Tee } // namespace
446