aboutsummaryrefslogtreecommitdiff
path: root/plugins/micromega
diff options
context:
space:
mode:
authorBESSON Frederic2020-11-02 18:46:37 +0100
committerBESSON Frederic2020-11-18 09:49:22 +0100
commit38e836a128d41a5de7dd72f1bf84f6350099aa43 (patch)
treec1e3e60d928a2255c0a1462d94a9ca7a0fbc555f /plugins/micromega
parent06a70885fe1ed03b6e71a7a0a1123db3074bcdeb (diff)
[micromega] Sort constraints before performing `subst`
This will be more predictable. In case there are several possible substitution, the "simplest" is prefered.
Diffstat (limited to 'plugins/micromega')
-rw-r--r--plugins/micromega/certificate.ml16
-rw-r--r--plugins/micromega/polynomial.ml18
-rw-r--r--plugins/micromega/polynomial.mli3
3 files changed, 21 insertions, 16 deletions
diff --git a/plugins/micromega/certificate.ml b/plugins/micromega/certificate.ml
index f1ae07892e..74d5374193 100644
--- a/plugins/micromega/certificate.ml
+++ b/plugins/micromega/certificate.ml
@@ -1061,20 +1061,6 @@ let elim_redundant sys = tr_sys "elim_redundant" elim_redundant sys
A necessary condition is to take the variable with the smallest coefficient *)
let fourier_small (sys : WithProof.t list) =
- let size ((p, o), prf) =
- let _, p' = Vect.decomp_cst p in
- let (x, q), p' = Vect.decomp_fst p' in
- Vect.fold
- (fun (l, (q, x)) x' q' ->
- let q' = Q.abs q' in
- (l + 1, if q </ q then (q, x) else (q', x')))
- (1, (Q.abs q, x))
- p
- in
- let cmp ((l1, (q1, _)), ((_, o), _)) ((l2, (q2, _)), ((_, o'), _)) =
- if l1 < l2 then -1 else if l1 = l2 then Q.compare q1 q2 else 1
- in
- let syss = List.sort cmp (List.rev_map (fun wp -> (size wp, wp)) sys) in
let gen_pivot acc (q, x) wp l =
List.fold_left
(fun acc (s, wp') ->
@@ -1091,7 +1077,7 @@ let fourier_small (sys : WithProof.t list) =
| [] -> acc
| ((_, qx), wp) :: l' -> all_pivots (gen_pivot acc qx wp (acc @ l')) l'
in
- List.rev_map snd (all_pivots [] syss)
+ List.rev_map snd (all_pivots [] (WithProof.sort sys))
let fourier_small = tr_sys "fourier_small" fourier_small
diff --git a/plugins/micromega/polynomial.ml b/plugins/micromega/polynomial.ml
index 1462ade7fb..7b29aa15f9 100644
--- a/plugins/micromega/polynomial.ml
+++ b/plugins/micromega/polynomial.ml
@@ -1081,6 +1081,22 @@ module WithProof = struct
| None -> sys0
| Some sys' -> sys' )
+ let sort (sys : t list) =
+ let size ((p, o), prf) =
+ let _, p' = Vect.decomp_cst p in
+ let (x, q), p' = Vect.decomp_fst p' in
+ Vect.fold
+ (fun (l, (q, x)) x' q' ->
+ let q' = Q.abs q' in
+ (l + 1, if q </ q then (q, x) else (q', x')))
+ (1, (Q.abs q, x))
+ p
+ in
+ let cmp ((l1, (q1, _)), ((_, o), _)) ((l2, (q2, _)), ((_, o'), _)) =
+ if l1 < l2 then -1 else if l1 = l2 then Q.compare q1 q2 else 1
+ in
+ List.sort cmp (List.rev_map (fun wp -> (size wp, wp)) sys)
+
let subst sys0 =
let elim sys =
let oeq, sys' = extract (is_substitution true) sys in
@@ -1088,7 +1104,7 @@ module WithProof = struct
| None -> None
| Some (v, pc) -> simplify (linear_pivot sys0 pc v) sys'
in
- iterate_until_stable elim sys0
+ iterate_until_stable elim (List.map snd (sort sys0))
let saturate_subst b sys0 =
let select = is_substitution b in
diff --git a/plugins/micromega/polynomial.mli b/plugins/micromega/polynomial.mli
index 4f59b76549..84b5421207 100644
--- a/plugins/micromega/polynomial.mli
+++ b/plugins/micromega/polynomial.mli
@@ -379,6 +379,9 @@ module WithProof : sig
p = c+a1.x1+....+c.x+...an.xn and c <> 0 *)
val simple_pivot : Q.t * var -> t -> t -> t option
+ (** [sort sys] sorts constraints according to the lexicographic order (number of variables, size of the smallest coefficient *)
+ val sort : t list -> ((int * (Q.t * var)) * t) list
+
(** [subst sys] performs the equivalent of the 'subst' tactic of Coq.
For every p=0 \in sys such that p is linear in x with coefficient +/- 1
i.e. p = 0 <-> x = e and x \notin e.