aboutsummaryrefslogtreecommitdiffhomepage
path: root/plugins/micromega/coq_micromega.ml
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/micromega/coq_micromega.ml')
-rw-r--r--plugins/micromega/coq_micromega.ml446
1 files changed, 265 insertions, 181 deletions
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 2d9dc781f..66fe5335c 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -24,7 +24,7 @@ let time str f x =
res
-type tag = int
+type tag = Tag.t
type 'cst atom = 'cst Micromega.formula
type 'cst formula =
@@ -43,7 +43,7 @@ let rec pp_formula o f =
| TT -> output_string o "tt"
| FF -> output_string o "ff"
| X c -> output_string o "X "
- | A(_,t,_) -> Printf.fprintf o "A(%i)" t
+ | A(_,t,_) -> Printf.fprintf o "A(%a)" Tag.pp t
| C(f1,f2) -> Printf.fprintf o "C(%a,%a)" pp_formula f1 pp_formula f2
| D(f1,f2) -> Printf.fprintf o "D(%a,%a)" pp_formula f1 pp_formula f2
| I(f1,n,f2) -> Printf.fprintf o "I(%a%s,%a)"
@@ -58,12 +58,15 @@ let rec ids_of_formula f =
| I(f1,Some id,f2) -> id::(ids_of_formula f2)
| _ -> []
-(* obsolete *)
+module ISet = Set.Make(struct type t = int let compare : int -> int -> int = Pervasives.compare end)
-let tag_formula t f = f (* to be removed *)
-(* obsolete *)
+let selecti s m =
+ let rec xselect i m =
+ match m with
+ | [] -> []
+ | e::m -> if ISet.mem i s then e:: (xselect (i+1) m) else xselect (i+1) m in
+ xselect 0 m
-module ISet = Set.Make(struct type t = int let compare : int -> int -> int = Pervasives.compare end)
type 'cst clause = ('cst Micromega.nFormula * tag) list
@@ -107,6 +110,7 @@ let cnf (negate: 'cst atom -> 'cst mc_cnf) (normalise:'cst atom -> 'cst mc_cnf)
xcnf true f
+
module M =
struct
open Coqlib
@@ -191,7 +195,8 @@ struct
let coq_R1 = lazy (constant "R1")
- let coq_proofTerm = lazy (constant "ProofTerm")
+ let coq_proofTerm = lazy (constant "ZArithProof")
+ let coq_doneProof = lazy (constant "DoneProof")
let coq_ratProof = lazy (constant "RatProof")
let coq_cutProof = lazy (constant "CutProof")
let coq_enumProof = lazy (constant "EnumProof")
@@ -245,6 +250,10 @@ struct
let coq_PEsub = lazy (constant "PEsub")
let coq_PEpow = lazy (constant "PEpow")
+ let coq_PX = lazy (constant "PX" )
+ let coq_Pc = lazy (constant"Pc")
+ let coq_Pinj = lazy (constant "Pinj")
+
let coq_OpEq = lazy (constant "OpEq")
let coq_OpNEq = lazy (constant "OpNEq")
@@ -254,14 +263,13 @@ struct
let coq_OpGt = lazy (constant "OpGt")
- let coq_S_In = lazy (constant "S_In")
- let coq_S_Square = lazy (constant "S_Square")
- let coq_S_Monoid = lazy (constant "S_Monoid")
- let coq_S_Ideal = lazy (constant "S_Ideal")
- let coq_S_Mult = lazy (constant "S_Mult")
- let coq_S_Add = lazy (constant "S_Add")
- let coq_S_Pos = lazy (constant "S_Pos")
- let coq_S_Z = lazy (constant "S_Z")
+ let coq_PsatzIn = lazy (constant "PsatzIn")
+ let coq_PsatzSquare = lazy (constant "PsatzSquare")
+ let coq_PsatzMulE = lazy (constant "PsatzMulE")
+ let coq_PsatzMultC = lazy (constant "PsatzMulC")
+ let coq_PsatzAdd = lazy (constant "PsatzAdd")
+ let coq_PsatzC = lazy (constant "PsatzC")
+ let coq_PsatzZ = lazy (constant "PsatzZ")
let coq_coneMember = lazy (constant "coneMember")
@@ -465,47 +473,64 @@ let parse_q term =
in
dump_expr e
- let rec dump_monoid l = dump_list (Lazy.force coq_nat) dump_nat l
- let rec dump_cone typ dump_z e =
+ let dump_pol typ dump_c e =
+ let rec dump_pol e =
+ match e with
+ | Mc.Pc n -> mkApp(Lazy.force coq_Pc, [|typ ; dump_c n|])
+ | Mc.Pinj(p,pol) -> mkApp(Lazy.force coq_Pinj , [| typ ; dump_positive p ; dump_pol pol|])
+ | Mc.PX(pol1,p,pol2) -> mkApp(Lazy.force coq_PX, [| typ ; dump_pol pol1 ; dump_positive p ; dump_pol pol2|]) in
+ dump_pol e
+
+ let pp_pol pp_c o e =
+ let rec pp_pol o e =
+ match e with
+ | Mc.Pc n -> Printf.fprintf o "Pc %a" pp_c n
+ | Mc.Pinj(p,pol) -> Printf.fprintf o "Pinj(%a,%a)" pp_positive p pp_pol pol
+ | Mc.PX(pol1,p,pol2) -> Printf.fprintf o "PX(%a,%a,%a)" pp_pol pol1 pp_positive p pp_pol pol2 in
+ pp_pol o e
+
+
+ let pp_cnf pp_c o f =
+ let pp_clause o l = List.iter (fun ((p,_),t) -> Printf.fprintf o "(%a @%a)" (pp_pol pp_c) p Tag.pp t) l in
+ List.iter (fun l -> Printf.fprintf o "[%a]" pp_clause l) f
+
+
+ let dump_psatz typ dump_z e =
let z = Lazy.force typ in
let rec dump_cone e =
match e with
- | Mc.S_In n -> mkApp(Lazy.force coq_S_In,[| z; dump_nat n |])
- | Mc.S_Ideal(e,c) -> mkApp(Lazy.force coq_S_Ideal,
- [| z; dump_expr z dump_z e ; dump_cone c |])
- | Mc.S_Square e -> mkApp(Lazy.force coq_S_Square,
- [| z;dump_expr z dump_z e|])
- | Mc.S_Monoid l -> mkApp (Lazy.force coq_S_Monoid,
- [|z; dump_monoid l|])
- | Mc.S_Add(e1,e2) -> mkApp(Lazy.force coq_S_Add,
+ | Mc.PsatzIn n -> mkApp(Lazy.force coq_PsatzIn,[| z; dump_nat n |])
+ | Mc.PsatzMulC(e,c) -> mkApp(Lazy.force coq_PsatzMultC,
+ [| z; dump_pol z dump_z e ; dump_cone c |])
+ | Mc.PsatzSquare e -> mkApp(Lazy.force coq_PsatzSquare,
+ [| z;dump_pol z dump_z e|])
+ | Mc.PsatzAdd(e1,e2) -> mkApp(Lazy.force coq_PsatzAdd,
[| z; dump_cone e1; dump_cone e2|])
- | Mc.S_Mult(e1,e2) -> mkApp(Lazy.force coq_S_Mult,
+ | Mc.PsatzMulE(e1,e2) -> mkApp(Lazy.force coq_PsatzMulE,
[| z; dump_cone e1; dump_cone e2|])
- | Mc.S_Pos p -> mkApp(Lazy.force coq_S_Pos,[| z; dump_z p|])
- | Mc.S_Z -> mkApp( Lazy.force coq_S_Z,[| z|]) in
+ | Mc.PsatzC p -> mkApp(Lazy.force coq_PsatzC,[| z; dump_z p|])
+ | Mc.PsatzZ -> mkApp( Lazy.force coq_PsatzZ,[| z|]) in
dump_cone e
- let pp_cone pp_z o e =
+ let pp_psatz pp_z o e =
let rec pp_cone o e =
match e with
- | Mc.S_In n ->
- Printf.fprintf o "(S_In %a)%%nat" pp_nat n
- | Mc.S_Ideal(e,c) ->
- Printf.fprintf o "(S_Ideal %a %a)" (pp_expr pp_z) e pp_cone c
- | Mc.S_Square e ->
- Printf.fprintf o "(S_Square %a)" (pp_expr pp_z) e
- | Mc.S_Monoid l ->
- Printf.fprintf o "(S_Monoid %a)" (pp_list "[" "]" pp_nat) l
- | Mc.S_Add(e1,e2) ->
- Printf.fprintf o "(S_Add %a %a)" pp_cone e1 pp_cone e2
- | Mc.S_Mult(e1,e2) ->
- Printf.fprintf o "(S_Mult %a %a)" pp_cone e1 pp_cone e2
- | Mc.S_Pos p ->
- Printf.fprintf o "(S_Pos %a)%%positive" pp_z p
- | Mc.S_Z ->
- Printf.fprintf o "S_Z" in
+ | Mc.PsatzIn n ->
+ Printf.fprintf o "(In %a)%%nat" pp_nat n
+ | Mc.PsatzMulC(e,c) ->
+ Printf.fprintf o "( %a [*] %a)" (pp_pol pp_z) e pp_cone c
+ | Mc.PsatzSquare e ->
+ Printf.fprintf o "(%a^2)" (pp_pol pp_z) e
+ | Mc.PsatzAdd(e1,e2) ->
+ Printf.fprintf o "(%a [+] %a)" pp_cone e1 pp_cone e2
+ | Mc.PsatzMulE(e1,e2) ->
+ Printf.fprintf o "(%a [*] %a)" pp_cone e1 pp_cone e2
+ | Mc.PsatzC p ->
+ Printf.fprintf o "(%a)%%positive" pp_z p
+ | Mc.PsatzZ ->
+ Printf.fprintf o "0" in
pp_cone o e
@@ -651,6 +676,7 @@ let parse_q term =
let (expr1,env) = parse_expr env t1 in
let (expr2,env) = parse_expr env t2 in
(op expr1 expr2,env) in
+
match kind_of_term term with
| App(t,args) ->
(
@@ -661,9 +687,14 @@ let parse_q term =
| Opp -> let (expr,env) = parse_expr env args.(0) in
(Mc.PEopp expr, env)
| Power ->
- let (expr,env) = parse_expr env args.(0) in
- let exp = (parse_exp args.(1)) in
- (Mc.PEpow(expr, exp) , env)
+ begin
+ try
+ let (expr,env) = parse_expr env args.(0) in
+ let exp = (parse_exp args.(1)) in
+ (Mc.PEpow(expr, exp) , env)
+ with _ -> (* if the exponent is a variable *)
+ let (env,n) = Env.compute_rank_add env term in (Mc.PEX n, env)
+ end
| Ukn s ->
if debug
then (Printf.printf "unknown op: %s\n" s; flush stdout;);
@@ -784,7 +815,7 @@ let parse_rexpr =
let parse_formula parse_atom env term =
let parse_atom env tg t = try let (at,env) = parse_atom env t in
- (A(at,tg,t), env,tg+1) with _ -> (X(t),env,tg) in
+ (A(at,tg,t), env,Tag.next tg) with _ -> (X(t),env,tg) in
let rec xparse_formula env tg term =
match kind_of_term term with
@@ -877,11 +908,11 @@ open M
let rec sig_of_cone = function
- | Mc.S_In n -> [CoqToCaml.nat n]
- | Mc.S_Ideal(e,w) -> sig_of_cone w
- | Mc.S_Mult(w1,w2) ->
+ | Mc.PsatzIn n -> [CoqToCaml.nat n]
+ | Mc.PsatzMulE(w1,w2) ->
(sig_of_cone w1)@(sig_of_cone w2)
- | Mc.S_Add(w1,w2) -> (sig_of_cone w1)@(sig_of_cone w2)
+ | Mc.PsatzMulC(w1,w2) -> (sig_of_cone w2)
+ | Mc.PsatzAdd(w1,w2) -> (sig_of_cone w1)@(sig_of_cone w2)
| _ -> []
let same_proof sg cl1 cl2 =
@@ -897,10 +928,10 @@ let same_proof sg cl1 cl2 =
let tags_of_clause tgs wit clause =
let rec xtags tgs = function
- | Mc.S_In n -> Names.Idset.union tgs
+ | Mc.PsatzIn n -> Names.Idset.union tgs
(snd (List.nth clause (CoqToCaml.nat n) ))
- | Mc.S_Ideal(e,w) -> xtags tgs w
- | Mc.S_Mult (w1,w2) | Mc.S_Add(w1,w2) -> xtags (xtags tgs w1) w2
+ | Mc.PsatzMulC(e,w) -> xtags tgs w
+ | Mc.PsatzMulE (w1,w2) | Mc.PsatzAdd(w1,w2) -> xtags (xtags tgs w1) w2
| _ -> tgs in
xtags tgs wit
@@ -975,29 +1006,28 @@ let rec pp_varmap o vm =
let rec dump_proof_term = function
- | Micromega.RatProof cone ->
- Term.mkApp(Lazy.force coq_ratProof, [|dump_cone coq_Z dump_z cone|])
- | Micromega.CutProof(e,q,cone,prf) ->
+ | Micromega.DoneProof -> Lazy.force coq_doneProof
+ | Micromega.RatProof(cone,rst) ->
+ Term.mkApp(Lazy.force coq_ratProof, [| dump_psatz coq_Z dump_z cone; dump_proof_term rst|])
+ | Micromega.CutProof(cone,prf) ->
Term.mkApp(Lazy.force coq_cutProof,
- [| dump_expr (Lazy.force coq_Z) dump_z e ;
- dump_q q ;
- dump_cone coq_Z dump_z cone ;
+ [| dump_psatz coq_Z dump_z cone ;
dump_proof_term prf|])
- | Micromega.EnumProof( q1,e1,q2,c1,c2,prfs) ->
+ | Micromega.EnumProof(c1,c2,prfs) ->
Term.mkApp (Lazy.force coq_enumProof,
- [| dump_q q1 ; dump_expr (Lazy.force coq_Z) dump_z e1 ; dump_q q2;
- dump_cone coq_Z dump_z c1 ; dump_cone coq_Z dump_z c2 ;
+ [| dump_psatz coq_Z dump_z c1 ; dump_psatz coq_Z dump_z c2 ;
dump_list (Lazy.force coq_proofTerm) dump_proof_term prfs |])
let pp_q o q = Printf.fprintf o "%a/%a" pp_z q.Micromega.qnum pp_positive q.Micromega.qden
let rec pp_proof_term o = function
- | Micromega.RatProof cone -> Printf.fprintf o "R[%a]" (pp_cone pp_z) cone
- | Micromega.CutProof(e,q,_,p) -> failwith "not implemented"
- | Micromega.EnumProof(q1,e1,q2,c1,c2,rst) ->
- Printf.fprintf o "EP[%a,%a,%a,%a,%a,%a]"
- pp_q q1 (pp_expr pp_z) e1 pp_q q2 (pp_cone pp_z) c1 (pp_cone pp_z) c2
+ | Micromega.DoneProof -> Printf.fprintf o "D"
+ | Micromega.RatProof(cone,rst) -> Printf.fprintf o "R[%a,%a]" (pp_psatz pp_z) cone pp_proof_term rst
+ | Micromega.CutProof(cone,rst) -> Printf.fprintf o "C[%a,%a]" (pp_psatz pp_z) cone pp_proof_term rst
+ | Micromega.EnumProof(c1,c2,rst) ->
+ Printf.fprintf o "EP[%a,%a,%a]"
+ (pp_psatz pp_z) c1 (pp_psatz pp_z) c2
(pp_list "[" "]" pp_proof_term) rst
let rec parse_hyps parse_arith env tg hyps =
@@ -1016,7 +1046,7 @@ exception ParseError
let parse_goal parse_arith env hyps term =
(* try*)
- let (f,env,tg) = parse_formula parse_arith env 0 term in
+ let (f,env,tg) = parse_formula parse_arith env (Tag.from 0) term in
let (lhyps,env,tg) = parse_hyps parse_arith env tg hyps in
(lhyps,f,env)
(* with Failure x -> raise ParseError*)
@@ -1043,7 +1073,7 @@ let qq_domain_spec = lazy {
coeff = Lazy.force coq_Q;
dump_coeff = dump_q ;
proof_typ = Lazy.force coq_QWitness ;
- dump_proof = dump_cone coq_Q dump_q
+ dump_proof = dump_psatz coq_Q dump_q
}
let rz_domain_spec = lazy {
@@ -1051,7 +1081,7 @@ let rz_domain_spec = lazy {
coeff = Lazy.force coq_Z;
dump_coeff = dump_z;
proof_typ = Lazy.force coq_ZWitness ;
- dump_proof = dump_cone coq_Z dump_z
+ dump_proof = dump_psatz coq_Z dump_z
}
@@ -1060,7 +1090,7 @@ let abstract_formula hyps f =
let rec xabs f =
match f with
| X c -> X c
- | A(a,t,term) -> if ISet.mem t hyps then A(a,t,term) else X(term)
+ | A(a,t,term) -> if TagSet.mem t hyps then A(a,t,term) else X(term)
| C(f1,f2) ->
(match xabs f1 , xabs f2 with
| X a1 , X a2 -> X (Term.mkApp(Lazy.force coq_and, [|a1;a2|]))
@@ -1079,8 +1109,10 @@ let abstract_formula hyps f =
| X a1 , None , X a2 -> X (Term.mkArrow a1 a2)
| af1 , _ , af2 -> I(af1,hyp,af2)
)
- | x -> x in
- xabs f
+ | FF -> FF
+ | TT -> TT
+
+ in xabs f
@@ -1125,21 +1157,6 @@ let find_witness provers polys1 =
try_any provers (List.map fst polys1)
-let witness_list_tags prover l =
-
- let rec xwitness_list l =
- match l with
- | [] -> Some([])
- | e::l ->
- match find_witness prover e with
- | None -> None
- | Some w ->
- (match xwitness_list l with
- | None -> None
- | Some l -> Some (w::l)
- ) in
- xwitness_list l
-
let witness_list prover l =
let rec xwitness_list l =
match l with
@@ -1155,6 +1172,8 @@ let witness_list prover l =
xwitness_list l
+let witness_list_tags = witness_list
+
let is_singleton = function [] -> true | [e] -> true | _ -> false
let pp_ml_list pp_elt o l =
@@ -1167,7 +1186,6 @@ let compact_proofs (cnf_ff: 'cst cnf) res (cnf_ff': 'cst cnf) =
let compact_proof (old_cl:'cst clause) (prf,prover) (new_cl:'cst clause) =
let new_cl = Mutils.mapi (fun (f,_) i -> (f,i)) new_cl in
let remap i =
- (*Printf.printf "nth (len:%i) %i\n" (List.length old_cl) i;*)
let formula = try fst (List.nth old_cl i) with Failure _ -> failwith "bad old index" in
List.assoc formula new_cl in
@@ -1179,12 +1197,13 @@ let compact_proofs (cnf_ff: 'cst cnf) res (cnf_ff': 'cst cnf) =
(pp_ml_list prover.pp_f) (List.map fst new_cl) ;
flush stdout
end ;
- let res = try prover.compact prf remap with x ->
+ let res = try prover.compact prf remap with x ->
+ if debug then Printf.fprintf stdout "Proof compaction %s" (Printexc.to_string x) ;
+
match prover.prover (List.map fst new_cl) with
- | None -> failwith "prover error"
+ | None -> failwith "proof compaction error"
| Some p -> p
in
-
if debug then
begin
Printf.printf " -> %a\n"
@@ -1194,11 +1213,19 @@ let compact_proofs (cnf_ff: 'cst cnf) res (cnf_ff': 'cst cnf) =
;
res in
+
+
+ let is_proof_compatible (old_cl:'cst clause) (prf,prover) (new_cl:'cst clause) =
+ let hyps_idx = prover.hyps prf in
+ let hyps = selecti hyps_idx old_cl in
+ is_sublist hyps new_cl in
+
let cnf_res = List.combine cnf_ff res in (* we get pairs clause * proof *)
- let l = (* This is not the right criterion for matching clauses *)
- List.map (fun x -> let (o,p) = List.find (fun lp -> is_sublist x (fst lp)) cnf_res in (o,p,x)) cnf_ff' in
- List.map (fun (o,p,n) -> compact_proof o p n) l
+ List.map (fun x ->
+ let (o,p) = List.find (fun (l,p) -> is_proof_compatible l p x) cnf_res
+ in compact_proof o p x) cnf_ff'
+
@@ -1220,33 +1247,47 @@ let micromega_tauto negate normalise spec prover env polys1 polys2 gl =
let formula_typ = (Term.mkApp( Lazy.force coq_Cstr,[| spec.coeff|])) in
let ff = dump_formula formula_typ
(dump_cstr spec.typ spec.dump_coeff) ff in
- Pp.pp (Printer.prterm ff) ; Pp.pp_flush ()
+ Pp.pp (Printer.prterm ff) ; Pp.pp_flush ();
+ Printf.fprintf stdout "cnf : %a\n" (pp_cnf (fun o _ -> ())) cnf_ff
end;
match witness_list_tags prover cnf_ff with
| None -> Tacticals.tclFAIL 0 (Pp.str "Cannot find witness") gl
- | Some res -> (*Printf.printf "\nList %i" (List.length res); *)
+ | Some res -> (*Printf.printf "\nList %i" (List.length `res); *)
+
let hyps = List.fold_left (fun s (cl,(prf,p)) ->
- let tags = ISet.fold (fun i s -> try ISet.add (snd (List.nth cl i)) s with Invalid_argument _ -> s) (p.hyps prf) ISet.empty in
- ISet.union s tags) ISet.empty (List.combine cnf_ff res) in
+ let tags = ISet.fold (fun i s -> let t = snd (List.nth cl i) in
+ if debug then (Printf.fprintf stdout "T : %i -> %a" i Tag.pp t) ;
+ (*try*) TagSet.add t s (* with Invalid_argument _ -> s*)) (p.hyps prf) TagSet.empty in
+ TagSet.union s tags) TagSet.empty (List.combine cnf_ff res) in
if debug then (Printf.printf "TForm : %a\n" pp_formula ff ; flush stdout;
- Printf.printf "Hyps : %a\n" (fun o s -> ISet.fold (fun i _ -> Printf.fprintf o "%i " i) s ()) hyps) ;
+ Printf.printf "Hyps : %a\n" (fun o s -> TagSet.fold (fun i _ -> Printf.fprintf o "%a " Tag.pp i) s ()) hyps) ;
let ff' = abstract_formula hyps ff in
+ let cnf_ff' = cnf negate normalise ff' in
+
if debug then
begin
Pp.pp (Pp.str "\nAFormula\n") ;
let formula_typ = (Term.mkApp( Lazy.force coq_Cstr,[| spec.coeff|])) in
let ff' = dump_formula formula_typ
(dump_cstr spec.typ spec.dump_coeff) ff' in
- Pp.pp (Printer.prterm ff') ; Pp.pp_flush ()
+ Pp.pp (Printer.prterm ff') ; Pp.pp_flush ();
+ Printf.fprintf stdout "cnf : %a\n" (pp_cnf (fun o _ -> ())) cnf_ff'
end;
-
- let cnf_ff' = cnf negate normalise ff' in
- let res' = compact_proofs cnf_ff res cnf_ff' in
+ (* Even if it does not work, this does not mean it is not provable
+ -- the prover is REALLY incomplete *)
+(* if debug then
+ begin
+ (* recompute the proofs *)
+ match witness_list_tags prover cnf_ff' with
+ | None -> failwith "abstraction is wrong"
+ | Some res -> ()
+ end ; *)
+ let res' = compact_proofs cnf_ff res cnf_ff' in
let (ff',res',ids) = (ff',res',List.map Term.mkVar (ids_of_formula ff')) in
@@ -1276,41 +1317,65 @@ let micromega_gen
| ParseError -> Tacticals.tclFAIL 0 (Pp.str "Bad logical fragment") gl
-let lift_ratproof prover l =
+let lift_ratproof prover l =
match prover l with
| None -> None
- | Some c -> Some (Mc.RatProof c)
-
+ | Some c -> Some (Mc.RatProof( c,Mc.DoneProof))
type csdpcert = Sos.positivstellensatz option
-type micromega_polys = (Micromega.q Mc.pExpr * Mc.op1) list
+type micromega_polys = (Mc.q Mc.pol * Mc.op1) list
type provername = string * int option
-let call_csdpcert provername poly =
- let tmp_to,ch_to = Filename.open_temp_file "csdpcert" ".in" in
- let tmp_from = Filename.temp_file "csdpcert" ".out" in
- output_value ch_to (provername,poly : provername * micromega_polys);
- close_out ch_to;
+open Persistent_cache
+
+module Cache = PHashtable(struct
+ type t = (provername * micromega_polys)
+ let equal = (=)
+ let hash = Hashtbl.hash
+end)
+
+let cache_name = "csdp.cache"
+
+let cache = lazy (Cache.open_in cache_name)
+
+
+let really_call_csdpcert : provername -> micromega_polys -> csdpcert =
+ fun provername poly ->
+
let cmdname =
List.fold_left Filename.concat (Envars.coqlib ())
["plugins"; "micromega"; "csdpcert" ^ Coq_config.exec_extension] in
- let c = Sys.command (cmdname ^" "^ tmp_to ^" "^ tmp_from) in
- (try Sys.remove tmp_to with _ -> ());
- if c <> 0 then Util.error ("Failed to call csdp certificate generator");
- let ch_from = open_in tmp_from in
- let cert = (input_value ch_from : csdpcert) in
- close_in ch_from; Sys.remove tmp_from;
- cert
-
-let rec z_to_q_expr e =
+
+ command cmdname [| cmdname |] (provername,poly)
+
+
+
+let call_csdpcert prover pb =
+
+ let cache = Lazy.force cache in
+ try
+ Cache.find cache (prover,pb)
+ with Not_found ->
+ let cert = really_call_csdpcert prover pb in
+ Cache.add cache (prover,pb) cert ;
+ cert
+
+
+
+
+
+
+
+
+
+
+
+
+let rec z_to_q_pol e =
match e with
- | Mc.PEc z -> Mc.PEc {Mc.qnum = z ; Mc.qden = Mc.XH}
- | Mc.PEX x -> Mc.PEX x
- | Mc.PEadd(e1,e2) -> Mc.PEadd(z_to_q_expr e1, z_to_q_expr e2)
- | Mc.PEsub(e1,e2) -> Mc.PEsub(z_to_q_expr e1, z_to_q_expr e2)
- | Mc.PEmul(e1,e2) -> Mc.PEmul(z_to_q_expr e1, z_to_q_expr e2)
- | Mc.PEopp(e) -> Mc.PEopp(z_to_q_expr e)
- | Mc.PEpow(e,n) -> Mc.PEpow(z_to_q_expr e,n)
+ | Mc.Pc z -> Mc.Pc {Mc.qnum = z ; Mc.qden = Mc.XH}
+ | Mc.Pinj(p,pol) -> Mc.Pinj(p,z_to_q_pol pol)
+ | Mc.PX(pol1,p,pol2) -> Mc.PX(z_to_q_pol pol1, p, z_to_q_pol pol2)
let call_csdpcert_q provername poly =
@@ -1324,7 +1389,7 @@ let call_csdpcert_q provername poly =
let call_csdpcert_z provername poly =
- let l = List.map (fun (e,o) -> (z_to_q_expr e,o)) poly in
+ let l = List.map (fun (e,o) -> (z_to_q_pol e,o)) poly in
match call_csdpcert provername l with
| None -> None
| Some cert ->
@@ -1334,45 +1399,51 @@ let call_csdpcert_z provername poly =
else ((print_string "buggy certificate" ; flush stdout) ;None)
-let hyps_of_cone prf =
+let xhyps_of_cone base acc prf =
let rec xtract e acc =
match e with
- | Mc.S_Pos _ | Mc.S_Z | Mc.S_Square _ -> acc
- | Mc.S_In n -> ISet.add (CoqToCaml.nat n) acc
- | Mc.S_Ideal(_,c) -> xtract c acc
- | Mc.S_Monoid [] -> acc
- | Mc.S_Monoid (i::l) -> xtract (Mc.S_Monoid l) (ISet.add (CoqToCaml.nat i) acc)
- | Mc.S_Add(e1,e2) | Mc.S_Mult(e1,e2) -> xtract e1 (xtract e2 acc) in
+ | Mc.PsatzC _ | Mc.PsatzZ | Mc.PsatzSquare _ -> acc
+ | Mc.PsatzIn n -> let n = (CoqToCaml.nat n) in
+ if n >= base
+ then ISet.add (n-base) acc
+ else acc
+ | Mc.PsatzMulC(_,c) -> xtract c acc
+ | Mc.PsatzAdd(e1,e2) | Mc.PsatzMulE(e1,e2) -> xtract e1 (xtract e2 acc) in
+
+ xtract prf acc
- xtract prf ISet.empty
+let hyps_of_cone prf = xhyps_of_cone 0 ISet.empty prf
let compact_cone prf f =
let np n = CamlToCoq.nat (f (CoqToCaml.nat n)) in
let rec xinterp prf =
match prf with
- | Mc.S_Pos _ | Mc.S_Z | Mc.S_Square _ -> prf
- | Mc.S_In n -> Mc.S_In (np n)
- | Mc.S_Ideal(e,c) -> Mc.S_Ideal(e,xinterp c)
- | Mc.S_Monoid l -> Mc.S_Monoid (Mc.map np l)
- | Mc.S_Add(e1,e2) -> Mc.S_Add(xinterp e1,xinterp e2)
- | Mc.S_Mult(e1,e2) -> Mc.S_Mult(xinterp e1,xinterp e2) in
+ | Mc.PsatzC _ | Mc.PsatzZ | Mc.PsatzSquare _ -> prf
+ | Mc.PsatzIn n -> Mc.PsatzIn (np n)
+ | Mc.PsatzMulC(e,c) -> Mc.PsatzMulC(e,xinterp c)
+ | Mc.PsatzAdd(e1,e2) -> Mc.PsatzAdd(xinterp e1,xinterp e2)
+ | Mc.PsatzMulE(e1,e2) -> Mc.PsatzMulE(xinterp e1,xinterp e2) in
xinterp prf
-
let hyps_of_pt pt =
- let translate x s = ISet.fold (fun i s -> ISet.add (i - x) s) s ISet.empty in
-
- let rec xhyps ofset pt acc =
+ let rec xhyps base pt acc =
match pt with
- | Mc.RatProof p -> ISet.union acc (translate ofset (hyps_of_cone p))
- | Mc.CutProof(_,_,c,pt) -> xhyps (ofset+1) pt (ISet.union (translate (ofset+1) (hyps_of_cone c)) acc)
- | Mc.EnumProof(_,_,_,c1,c2,l) ->
- let s = ISet.union acc (translate (ofset +1) (ISet.union (hyps_of_cone c1) (hyps_of_cone c2))) in
- List.fold_left (fun s x -> xhyps (ofset + 1) x s) s l in
+ | Mc.DoneProof -> acc
+ | Mc.RatProof(c,pt) -> xhyps (base+1) pt (xhyps_of_cone base acc c)
+ | Mc.CutProof(c,pt) -> xhyps (base+1) pt (xhyps_of_cone base acc c)
+ | Mc.EnumProof(c1,c2,l) ->
+ let s = xhyps_of_cone base (xhyps_of_cone base acc c2) c1 in
+ List.fold_left (fun s x -> xhyps (base + 1) x s) s l in
xhyps 0 pt ISet.empty
+
+let hyps_of_pt pt =
+ let res = hyps_of_pt pt in
+ if debug
+ then (Printf.fprintf stdout "\nhyps_of_pt : %a -> " pp_proof_term pt ; ISet.iter (fun i -> Printf.printf "%i " i) res);
+ res
let compact_pt pt f =
@@ -1382,39 +1453,44 @@ let compact_pt pt f =
let rec compact_pt ofset pt =
match pt with
- | Mc.RatProof p -> Mc.RatProof (compact_cone p (translate ofset))
- | Mc.CutProof(x,y,c,pt) -> Mc.CutProof(x,y,compact_cone c (translate (ofset+1)), compact_pt (ofset+1) pt )
- | Mc.EnumProof(a,b,c,c1,c2,l) -> Mc.EnumProof(a,b,c,compact_cone c1 (translate (ofset+1)), compact_cone c2 (translate (ofset+1)),
+ | Mc.DoneProof -> Mc.DoneProof
+ | Mc.RatProof(c,pt) -> Mc.RatProof(compact_cone c (translate (ofset)), compact_pt (ofset+1) pt )
+ | Mc.CutProof(c,pt) -> Mc.CutProof(compact_cone c (translate (ofset)), compact_pt (ofset+1) pt )
+ | Mc.EnumProof(c1,c2,l) -> Mc.EnumProof(compact_cone c1 (translate (ofset)), compact_cone c2 (translate (ofset)),
Mc.map (fun x -> compact_pt (ofset+1) x) l) in
compact_pt 0 pt
+
+
(** Definition of provers *)
-
+
+let lift_pexpr_prover p l = p (List.map (fun (e,o) -> Mc.denorm e , o) l)
+
let linear_prover_Z = {
name = "linear prover" ;
- prover = lift_ratproof (Certificate.linear_prover Certificate.z_spec) ;
+ prover = lift_ratproof (lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.z_spec)) ;
hyps = hyps_of_pt ;
compact = compact_pt ;
pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_expr pp_z o (fst x)
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
let linear_prover_Q = {
name = "linear prover";
- prover = (Certificate.linear_prover Certificate.q_spec) ;
+ prover = lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.q_spec) ;
hyps = hyps_of_cone ;
compact = compact_cone ;
- pp_prf = pp_cone pp_q ;
- pp_f = fun o x -> pp_expr pp_q o (fst x)
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let linear_prover_R = {
name = "linear prover";
- prover = (Certificate.linear_prover Certificate.z_spec) ;
+ prover = lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.z_spec) ;
hyps = hyps_of_cone ;
compact = compact_cone ;
- pp_prf = pp_cone pp_z ;
- pp_f = fun o x -> pp_expr pp_z o (fst x)
+ pp_prf = pp_psatz pp_z ;
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
let non_linear_prover_Q str o = {
@@ -1422,8 +1498,8 @@ let non_linear_prover_Q str o = {
prover = call_csdpcert_q (str, o);
hyps = hyps_of_cone;
compact = compact_cone ;
- pp_prf = pp_cone pp_q ;
- pp_f = fun o x -> pp_expr pp_q o (fst x)
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let non_linear_prover_R str o = {
@@ -1431,8 +1507,8 @@ let non_linear_prover_R str o = {
prover = call_csdpcert_z (str, o);
hyps = hyps_of_cone;
compact = compact_cone;
- pp_prf = pp_cone pp_z;
- pp_f = fun o x -> pp_expr pp_z o (fst x)
+ pp_prf = pp_psatz pp_z;
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
let non_linear_prover_Z str o = {
@@ -1441,16 +1517,19 @@ let non_linear_prover_Z str o = {
hyps = hyps_of_pt;
compact = compact_pt;
pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_expr pp_z o (fst x)
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
+
+
+
let linear_Z = {
name = "lia";
- prover = Certificate.zlinear_prover ;
+ prover = lift_pexpr_prover Certificate.zlinear_prover ;
hyps = hyps_of_pt;
compact = compact_pt;
pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_expr pp_z o (fst x)
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
@@ -1461,22 +1540,23 @@ let psatzl_Z gl =
micromega_gen parse_zarith Mc.negate Mc.normalise zz_domain_spec
[linear_prover_Z ] gl
+
let psatzl_Q gl =
- micromega_gen parse_qarith Mc.cnf_negate Mc.cnf_normalise qq_domain_spec
+ micromega_gen parse_qarith Mc.qnegate Mc.qnormalise qq_domain_spec
[ linear_prover_Q ] gl
let psatz_Q i gl =
- micromega_gen parse_qarith Mc.cnf_negate Mc.cnf_normalise qq_domain_spec
+ micromega_gen parse_qarith Mc.qnegate Mc.qnormalise qq_domain_spec
[ non_linear_prover_Q "real_nonlinear_prover" (Some i) ] gl
let psatzl_R gl =
- micromega_gen parse_rarith Mc.cnf_negate Mc.cnf_normalise rz_domain_spec
+ micromega_gen parse_rarith Mc.rnegate Mc.rnormalise rz_domain_spec
[ linear_prover_R ] gl
let psatz_R i gl =
- micromega_gen parse_rarith Mc.cnf_negate Mc.cnf_normalise rz_domain_spec
+ micromega_gen parse_rarith Mc.rnegate Mc.rnormalise rz_domain_spec
[ non_linear_prover_R "real_nonlinear_prover" (Some i)] gl
@@ -1490,12 +1570,12 @@ let sos_Z gl =
[non_linear_prover_Z "pure_sos" None] gl
let sos_Q gl =
- micromega_gen parse_qarith Mc.cnf_negate Mc.cnf_normalise qq_domain_spec
+ micromega_gen parse_qarith Mc.qnegate Mc.qnormalise qq_domain_spec
[non_linear_prover_Q "pure_sos" None] gl
let sos_R gl =
- micromega_gen parse_rarith Mc.cnf_negate Mc.cnf_normalise rz_domain_spec
+ micromega_gen parse_rarith Mc.rnegate Mc.rnormalise rz_domain_spec
[non_linear_prover_R "pure_sos" None] gl
@@ -1503,3 +1583,7 @@ let sos_R gl =
let xlia gl =
micromega_gen parse_zarith Mc.negate Mc.normalise zz_domain_spec
[linear_Z] gl
+
+(* Local Variables: *)
+(* coding: utf-8 *)
+(* End: *)