2 #include <cxxtest/TestSuite.h>
4 #include "theory/theory.h"
5 #include "theory/arith/theory_arith.h"
7 #include "expr/node_manager.h"
8 #include "context/context.h"
9 #include "util/rational.h"
11 #include "theory/theory_test_utils.h"
16 using namespace CVC4::theory
;
17 using namespace CVC4::theory::arith
;
18 using namespace CVC4::expr
;
19 using namespace CVC4::context
;
20 using namespace CVC4::kind
;
24 class TheoryArithWhite
: public CxxTest::TestSuite
{
28 NodeManagerScope
* d_scope
;
30 TestOutputChannel d_outputChannel
;
31 Theory::Effort d_level
;
35 TypeNode
* d_booleanType
;
38 const Rational d_zero
;
41 std::set
<Node
>* preregistered
;
47 TheoryArithWhite() : d_level(Theory::FULL_EFFORT
), d_zero(0), d_one(1), debug(false) {}
51 d_nm
= new NodeManager(d_ctxt
);
52 d_scope
= new NodeManagerScope(d_nm
);
53 d_outputChannel
.clear();
54 d_arith
= new TheoryArith(d_ctxt
, d_outputChannel
);
56 preregistered
= new std::set
<Node
>();
58 d_booleanType
= new TypeNode(d_nm
->booleanType());
59 d_realType
= new TypeNode(d_nm
->realType());
70 d_outputChannel
.clear();
76 Node
fakeTheoryEnginePreprocess(TNode inp
){
77 Node rewrite
= d_arith
->rewrite(inp
);
79 if(debug
) cout
<< rewrite
<< inp
<< endl
;
81 std::list
<Node
> toPreregister
;
83 toPreregister
.push_back(rewrite
);
84 for(std::list
<Node
>::iterator i
= toPreregister
.begin(); i
!= toPreregister
.end(); ++i
){
86 preregistered
->insert(n
);
88 for(Node::iterator citer
= n
.begin(); citer
!= n
.end(); ++citer
){
90 if(preregistered
->find(c
) == preregistered
->end()){
91 toPreregister
.push_back(c
);
95 for(std::list
<Node
>::reverse_iterator i
= toPreregister
.rbegin(); i
!= toPreregister
.rend(); ++i
){
97 if(debug
) cout
<< n
.getId() << " "<< n
<< endl
;
98 d_arith
->preRegisterTerm(n
);
105 Node x
= d_nm
->mkVar(*d_realType
);
106 Node c
= d_nm
->mkConst
<Rational
>(d_zero
);
108 Node leq
= d_nm
->mkNode(LEQ
, x
, c
);
109 Node rLeq
= fakeTheoryEnginePreprocess(leq
);
111 d_arith
->assertFact(rLeq
);
113 d_arith
->check(d_level
);
115 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 0u);
118 Node
simulateSplit(TNode l
, TNode r
){
119 Node eq
= d_nm
->mkNode(EQUAL
, l
, r
);
120 Node lt
= d_nm
->mkNode(LT
, l
, r
);
121 Node gt
= d_nm
->mkNode(GT
, l
, r
);
123 Node dis
= d_nm
->mkNode(OR
, eq
, lt
, gt
);
127 void testAssertEqualityEagerSplit() {
128 Node x
= d_nm
->mkVar(*d_realType
);
129 Node c
= d_nm
->mkConst
<Rational
>(d_zero
);
131 Node eq
= d_nm
->mkNode(EQUAL
, x
, c
);
132 Node expectedDisjunct
= simulateSplit(x
,c
);
134 Node rEq
= fakeTheoryEnginePreprocess(eq
);
136 d_arith
->assertFact(rEq
);
138 d_arith
->check(d_level
);
140 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 1u);
142 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(0), expectedDisjunct
);
143 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(0), AUG_LEMMA
);
146 void testLtRewrite() {
147 Node x
= d_nm
->mkVar(*d_realType
);
148 Node c
= d_nm
->mkConst
<Rational
>(d_zero
);
150 Node lt
= d_nm
->mkNode(LT
, x
, c
);
151 Node geq
= d_nm
->mkNode(GEQ
, x
, c
);
152 Node expectedRewrite
= d_nm
->mkNode(NOT
, geq
);
154 Node rewrite
= d_arith
->rewrite(lt
);
156 TS_ASSERT_EQUALS(expectedRewrite
, rewrite
);
159 void testBasicConflict() {
160 Node x
= d_nm
->mkVar(*d_realType
);
161 Node c
= d_nm
->mkConst
<Rational
>(d_zero
);
163 Node eq
= d_nm
->mkNode(EQUAL
, x
, c
);
164 Node lt
= d_nm
->mkNode(LT
, x
, c
);
165 Node expectedDisjunct
= simulateSplit(x
,c
);
167 Node rEq
= fakeTheoryEnginePreprocess(eq
);
168 Node rLt
= fakeTheoryEnginePreprocess(lt
);
170 d_arith
->assertFact(rEq
);
171 d_arith
->assertFact(rLt
);
174 d_arith
->check(d_level
);
176 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 2u);
177 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(0), expectedDisjunct
);
178 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(0), AUG_LEMMA
);
180 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(1), CONFLICT
);
182 Node expectedClonflict
= d_nm
->mkNode(AND
, rEq
, rLt
);
184 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(1), expectedClonflict
);
187 void testBasicPropagate() {
188 Node x
= d_nm
->mkVar(*d_realType
);
189 Node c
= d_nm
->mkConst
<Rational
>(d_zero
);
191 Node eq
= d_nm
->mkNode(EQUAL
, x
, c
);
192 Node lt
= d_nm
->mkNode(LT
, x
, c
);
193 Node expectedDisjunct
= simulateSplit(x
,c
);
195 Node rEq
= fakeTheoryEnginePreprocess(eq
);
196 Node rLt
= fakeTheoryEnginePreprocess(lt
);
198 d_arith
->assertFact(rEq
);
201 d_arith
->check(d_level
);
202 d_arith
->propagate(d_level
);
204 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 2u);
205 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(0), AUG_LEMMA
);
208 Node expectedProp
= d_nm
->mkNode(GEQ
, x
, c
);
209 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(1), PROPAGATE
);
210 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(1), expectedProp
);
214 Node x
= d_nm
->mkVar(*d_realType
);
215 Node c0
= d_nm
->mkConst
<Rational
>(d_zero
);
216 Node c1
= d_nm
->mkConst
<Rational
>(d_one
);
218 Node leq0
= d_nm
->mkNode(LEQ
, x
, c0
);
219 Node leq1
= d_nm
->mkNode(LEQ
, x
, c1
);
220 Node lt1
= d_nm
->mkNode(LT
, x
, c1
);
222 Node rLeq0
= fakeTheoryEnginePreprocess(leq0
);
223 Node rLt1
= fakeTheoryEnginePreprocess(lt1
);
224 Node rLeq1
= fakeTheoryEnginePreprocess(leq1
);
226 d_arith
->assertFact(rLt1
);
229 d_arith
->check(d_level
);
230 d_arith
->propagate(d_level
);
232 #ifdef CVC4_ASSERTIONS
233 TS_ASSERT_THROWS( d_arith
->explain(rLeq0
, d_level
), AssertionException
);
234 TS_ASSERT_THROWS( d_arith
->explain(rLt1
, d_level
), AssertionException
);
236 d_arith
->explain(rLeq1
, d_level
);
238 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 2u);
239 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(0), PROPAGATE
);
240 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(1), EXPLANATION
);
241 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(0), leq1
);
242 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(1), rLt1
);
247 Node x
= d_nm
->mkVar(*d_realType
);
248 Node c0
= d_nm
->mkConst
<Rational
>(d_zero
);
249 Node c1
= d_nm
->mkConst
<Rational
>(d_one
);
251 Node leq0
= d_nm
->mkNode(LEQ
, x
, c0
);
252 Node leq1
= d_nm
->mkNode(LEQ
, x
, c1
);
253 Node lt1
= d_nm
->mkNode(LT
, x
, c1
);
255 Node rLeq0
= fakeTheoryEnginePreprocess(leq0
);
256 Node rLt1
= fakeTheoryEnginePreprocess(lt1
);
257 Node rLeq1
= fakeTheoryEnginePreprocess(leq1
);
259 d_arith
->assertFact(rLeq0
);
262 d_arith
->check(d_level
);
263 d_arith
->propagate(d_level
);
266 d_arith
->explain(rLt1
, d_level
);
267 #ifdef CVC4_ASSERTIONS
268 TS_ASSERT_THROWS( d_arith
->explain(rLeq0
, d_level
), AssertionException
);
270 d_arith
->explain(rLeq1
, d_level
);
272 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 4u);
273 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(0), PROPAGATE
);
274 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(1), PROPAGATE
);
275 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(2), EXPLANATION
);
276 TS_ASSERT_EQUALS(d_outputChannel
.getIthCallType(3), EXPLANATION
);
278 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(1), rLt1
);
279 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(0), rLeq1
);
282 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(2), rLeq0
);
283 TS_ASSERT_EQUALS(d_outputChannel
.getIthNode(3), rLeq0
);
286 Node x
= d_nm
->mkVar(*d_realType
);
287 Node c0
= d_nm
->mkConst
<Rational
>(d_zero
);
288 Node c1
= d_nm
->mkConst
<Rational
>(d_one
);
290 Node leq0
= d_nm
->mkNode(LEQ
, x
, c0
);
291 Node leq1
= d_nm
->mkNode(LEQ
, x
, c1
);
292 Node lt1
= d_nm
->mkNode(LT
, x
, c1
);
294 Node rLeq0
= fakeTheoryEnginePreprocess(leq0
);
295 Node rLt1
= fakeTheoryEnginePreprocess(lt1
);
296 Node rLeq1
= fakeTheoryEnginePreprocess(leq1
);
298 d_arith
->assertFact(rLeq1
);
301 d_arith
->check(d_level
);
302 d_arith
->propagate(d_level
);
304 #ifdef CVC4_ASSERTIONS
305 TS_ASSERT_THROWS( d_arith
->explain(rLeq0
, d_level
), AssertionException
);
306 TS_ASSERT_THROWS( d_arith
->explain(rLeq1
, d_level
), AssertionException
);
307 TS_ASSERT_THROWS( d_arith
->explain(rLt1
, d_level
), AssertionException
);
310 TS_ASSERT_EQUALS(d_outputChannel
.getNumCalls(), 0u);