mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-09 20:55:39 -05:00
fix(simplex2): add basic var's bound in the certificate
This commit is contained in:
parent
0081926a50
commit
69b2fde084
1 changed files with 21 additions and 12 deletions
|
|
@ -615,6 +615,7 @@ module Make(Var: VAR)
|
||||||
}
|
}
|
||||||
| E_unsat_basic of {
|
| E_unsat_basic of {
|
||||||
x: var_state;
|
x: var_state;
|
||||||
|
x_bound: (Op.t * bound);
|
||||||
le: (num * V.t) list; (* definition of the basic var *)
|
le: (num * V.t) list; (* definition of the basic var *)
|
||||||
bounds: (Op.t * bound) V_map.t; (* bound for each variable in [le] *)
|
bounds: (Op.t * bound) V_map.t; (* bound for each variable in [le] *)
|
||||||
}
|
}
|
||||||
|
|
@ -624,25 +625,27 @@ module Make(Var: VAR)
|
||||||
|
|
||||||
let lits = function
|
let lits = function
|
||||||
| E_bounds b -> [b.lower.b_lit; b.upper.b_lit]
|
| E_bounds b -> [b.lower.b_lit; b.upper.b_lit]
|
||||||
| E_unsat_basic b ->
|
| E_unsat_basic {x_bound=(_,x_bnd); bounds; x=_; le=_;} ->
|
||||||
V_map.fold (fun _ (_,bnd) l -> bnd.b_lit :: l) b.bounds []
|
V_map.fold (fun _ (_,bnd) l -> bnd.b_lit :: l) bounds [x_bnd.b_lit]
|
||||||
|
|
||||||
let pp out (self:t) =
|
let pp out (self:t) =
|
||||||
match self with
|
match self with
|
||||||
| E_bounds {x;lower;upper} ->
|
| E_bounds {x;lower;upper} ->
|
||||||
Fmt.fprintf out "(@[unsat-bounds@ %a@ :lower %a@ :upper %a@])"
|
Fmt.fprintf out "(@[cert.unsat-bounds@ %a@ :lower %a@ :upper %a@])"
|
||||||
Var_state.pp x Erat.pp lower.b_val Erat.pp upper.b_val
|
Var_state.pp x Erat.pp lower.b_val Erat.pp upper.b_val
|
||||||
| E_unsat_basic {x; le; bounds} ->
|
| E_unsat_basic {x; x_bound; le; bounds} ->
|
||||||
let pp_bnd out (v,(op,bnd)) =
|
let pp_bnd out (v,(op,bnd)) =
|
||||||
Fmt.fprintf out "(@[%a %s %a@])" Var.pp v (Op.to_string op) Erat.pp bnd.b_val
|
Fmt.fprintf out "(@[%a %s %a@])" Var.pp v (Op.to_string op) Erat.pp bnd.b_val
|
||||||
in
|
in
|
||||||
Fmt.fprintf out "(@[cert@ %a :bounds %a@ :defs %a@])"
|
Fmt.fprintf out
|
||||||
Var_state.pp x
|
"(@[cert.unsat-basic@ %a@ @[:bound %a@] @[:le %a@]@ @[:le-bounds@ %a@]@])"
|
||||||
|
Var_state.pp x pp_bnd (x.var,x_bound)
|
||||||
Fmt.(Dump.list pp_bnd) (V_map.to_list bounds)
|
Fmt.(Dump.list pp_bnd) (V_map.to_list bounds)
|
||||||
Fmt.(Dump.list (Dump.pair pp_q_dbg V.pp)) le
|
Fmt.(Dump.list (Dump.pair pp_q_dbg V.pp)) le
|
||||||
|
|
||||||
let bounds x ~lower ~upper : t = E_bounds {x; lower; upper}
|
let bounds x ~lower ~upper : t = E_bounds {x; lower; upper}
|
||||||
let unsat_basic x le bounds : t = E_unsat_basic {x; le; bounds}
|
let unsat_basic x x_bound le bounds : t =
|
||||||
|
E_unsat_basic {x; x_bound; le; bounds}
|
||||||
end
|
end
|
||||||
|
|
||||||
exception E_unsat of Unsat_cert.t
|
exception E_unsat of Unsat_cert.t
|
||||||
|
|
@ -751,7 +754,7 @@ module Make(Var: VAR)
|
||||||
one of its bound, and whose row is tight on all non-basic variables.
|
one of its bound, and whose row is tight on all non-basic variables.
|
||||||
@param is_lower is true if the lower bound is not respected
|
@param is_lower is true if the lower bound is not respected
|
||||||
(i.e. [x_i] is too small) *)
|
(i.e. [x_i] is too small) *)
|
||||||
let cert_of_row_ (self:t) (x_i:var_state) ~is_lower : unsat_cert =
|
let cert_of_row_ (self:t) (x_i:var_state) (bnd:bound) ~is_lower : unsat_cert =
|
||||||
Log.debugf 50 (fun k->k "(@[simplex.cert-of-row[lower: %B]@ x_i=%a@])"
|
Log.debugf 50 (fun k->k "(@[simplex.cert-of-row[lower: %B]@ x_i=%a@])"
|
||||||
is_lower Var_state.pp x_i);
|
is_lower Var_state.pp x_i);
|
||||||
assert (Var_state.is_basic x_i);
|
assert (Var_state.is_basic x_i);
|
||||||
|
|
@ -783,7 +786,13 @@ module Make(Var: VAR)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
self.vars;
|
self.vars;
|
||||||
let cert = Unsat_cert.unsat_basic x_i !le !bounds in
|
|
||||||
|
let op =
|
||||||
|
if is_lower then if Q.(bnd.b_val.eps_factor <= zero) then Op.Geq else Op.Gt
|
||||||
|
else if Q.(bnd.b_val.eps_factor >= zero) then Op.Leq else Op.Lt
|
||||||
|
in
|
||||||
|
|
||||||
|
let cert = Unsat_cert.unsat_basic x_i (op, bnd) !le !bounds in
|
||||||
cert
|
cert
|
||||||
|
|
||||||
(* main satisfiability check.
|
(* main satisfiability check.
|
||||||
|
|
@ -796,7 +805,7 @@ module Make(Var: VAR)
|
||||||
try
|
try
|
||||||
while true do
|
while true do
|
||||||
_check_invariants_internal self;
|
_check_invariants_internal self;
|
||||||
Log.debugf 50 (fun k->k "(@[simplex2.check.iter@ %a@])" pp self);
|
(* Log.debugf 50 (fun k->k "(@[simplex2.check.iter@ %a@])" pp self); *)
|
||||||
|
|
||||||
(* basic variable that doesn't respect its bound *)
|
(* basic variable that doesn't respect its bound *)
|
||||||
let x_i, is_lower, bnd = match find_basic_var_ self with
|
let x_i, is_lower, bnd = match find_basic_var_ self with
|
||||||
|
|
@ -817,7 +826,7 @@ module Make(Var: VAR)
|
||||||
with
|
with
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
| None ->
|
| None ->
|
||||||
let cert = cert_of_row_ self x_i ~is_lower:true in
|
let cert = cert_of_row_ self x_i bnd ~is_lower:true in
|
||||||
raise (E_unsat cert)
|
raise (E_unsat cert)
|
||||||
in
|
in
|
||||||
assert (Var_state.is_n_basic x_j);
|
assert (Var_state.is_n_basic x_j);
|
||||||
|
|
@ -839,7 +848,7 @@ module Make(Var: VAR)
|
||||||
with
|
with
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
| None ->
|
| None ->
|
||||||
let cert = cert_of_row_ self x_i ~is_lower:false in
|
let cert = cert_of_row_ self x_i bnd ~is_lower:false in
|
||||||
raise (E_unsat cert)
|
raise (E_unsat cert)
|
||||||
in
|
in
|
||||||
assert (Var_state.is_n_basic x_j);
|
assert (Var_state.is_n_basic x_j);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue