@@ -212,7 +212,24 @@ bool order::order_lemma_on_ac_and_bc(const monic& rm_ac,
212
212
// We try to find a monic n = cd, such that |b| = |d|
213
213
// and get a lemma m R n & |b| = |d| => ab/|b| R cd /|d|, where R is a relation
214
214
void order::order_lemma_on_factorization (const monic& m, const factorization& ab) {
215
+ bool sign = m.rsign ();
216
+ for (factor f: ab)
217
+ sign ^= _ ().canonize_sign (f);
218
+ const rational rsign = sign_to_rat (sign);
219
+ const rational fv = val (var (ab[0 ])) * val (var (ab[1 ]));
220
+ const rational mv = rsign * var_val (m);
221
+ TRACE (" nla_solver" ,
222
+ tout << " ab.size()=" << ab.size () << " \n " ;
223
+ tout << " we should have sign*var_val(m):" << mv << " =(" << rsign << " )*(" << var_val (m) <<" ) to be equal to " << " val(var(ab[0]))*val(var(ab[1])):" << fv << " \n " ;);
215
224
TRACE (" nla_solver" , tout << " m=" ; _ ().print_monic_with_vars (m, tout); tout << " \n factorization=" ; _ ().print_factorization (ab, tout););
225
+ if (mv != fv) {
226
+ bool gt = mv > fv;
227
+ for (unsigned j = 0 , k = 1 ; j < 2 ; j++, k--) {
228
+ order_lemma_on_ab (m, rsign, var (ab[k]), var (ab[j]), gt);
229
+ explain (ab); explain (m);
230
+ TRACE (" nla_solver" , _ ().print_lemma (tout););
231
+ }
232
+ }
216
233
for (unsigned j = 0 , k = 1 ; j < 2 ; j++, k--) {
217
234
order_lemma_on_ac_explore (m, ab, j == 1 );
218
235
}
@@ -316,5 +333,38 @@ bool order::order_lemma_on_ac_and_bc_and_factors(const monic& ac,
316
333
}
317
334
return false ;
318
335
}
336
+ /*
337
+ given: sign * m = ab
338
+ lemma b != val(b) || sign 0 m <= a*val(b)
339
+ */
340
+ void order::order_lemma_on_ab_gt (const monic& m, const rational& sign, lpvar a, lpvar b) {
341
+ SASSERT (sign * var_val (m) > val (a) * val (b));
342
+ add_lemma ();
343
+ // negate b == val(b)
344
+ mk_ineq (b, llc::NE, val (b));
345
+ // ab <= val(b)a
346
+ mk_ineq (sign, m.var (), -val (b), a, llc::LE);
347
+ }
348
+ /*
349
+ given: sign * m = ab
350
+ lemma b != val(b) || sign*m >= a*val(b)
351
+ */
352
+ void order::order_lemma_on_ab_lt (const monic& m, const rational& sign, lpvar a, lpvar b) {
353
+ TRACE (" nla_solver" , tout << " sign = " << sign << " , m = " ; c ().print_monic (m, tout) << " , a = " ; c ().print_var (a, tout) <<
354
+ " , b = " ; c ().print_var (b, tout) << " \n " ;);
355
+ SASSERT (sign * var_val (m) < val (a) * val (b));
356
+ add_lemma ();
357
+ // negate b == val(b)
358
+ mk_ineq (b, llc::NE, val (b));
359
+ // ab >= val(b)a
360
+ mk_ineq (sign, m.var (), -val (b), a, llc::GE);
361
+ }
362
+
363
+ void order::order_lemma_on_ab (const monic& m, const rational& sign, lpvar a, lpvar b, bool gt) {
364
+ if (gt)
365
+ order_lemma_on_ab_gt (m, sign, a, b);
366
+ else
367
+ order_lemma_on_ab_lt (m, sign, a, b);
368
+ }
319
369
320
370
}
0 commit comments