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