(* Title: HOL/Tools/Function/scnp_solve.ML Author: Armin Heller, TU Muenchen Author: Alexander Krauss, TU Muenchen
Certificate generation for SCNP using a SAT solver.
*)
signature SCNP_SOLVE = sig
datatype edge = GTR | GEQ datatype graph = G of int * int * (int * edge * int) list datatype graph_problem = GP of int list * graph list
datatype label = MIN | MAX | MS
type certificate =
label (* which order *)
* (int * int) listlist(* (multi)sets *)
* int list(* strictly ordered calls *)
* (int -> bool -> int -> (int * int) option) (* covering function *)
val generate_certificate : bool -> label list -> graph_problem -> certificate option
val solver : string Unsynchronized.ref end
structure ScnpSolve : SCNP_SOLVE = struct
(** Graph problems **)
datatype edge = GTR | GEQ ; datatype graph = G of int * int * (int * edge * int) list ; datatype graph_problem = GP of int list * graph list ;
datatype label = MIN | MAX | MS ; type certificate =
label
* (int * int) listlist
* int list
* (int -> bool -> int -> (int * int) option)
fun graph_at (GP (_, gs), i) = nth gs i ; fun num_prog_pts (GP (arities, _)) = length arities ; fun num_graphs (GP (_, gs)) = length gs ; fun arity (GP (arities, gl)) i = nth arities i ; fun ndigits (GP (arities, _)) = Integer.log2 (Integer.sum arities) + 1
(** Propositional formulas **)
valNot = Prop_Logic.NotandAnd = Prop_Logic.AndandOr = Prop_Logic.Or val BoolVar = Prop_Logic.BoolVar fun Implies (p, q) = Or (Not p, q) fun Equiv (p, q) = And (Implies (p, q), Implies (q, p)) valall = Prop_Logic.all
(* finite indexed quantifiers:
iforall n f <==> /\ / \ f i 0<=i<n
*) fun iforall n f = all (map_range f n) fun iexists n f = Prop_Logic.exists (map_range f n) fun iforall2 n m f = all (map_product f (0 upto n - 1) (0 upto m - 1))
fun the_one var n x = all (var x :: map (Not o var) (remove (op =) x (0 upto n - 1))) fun exactly_one n f = iexists n (the_one f n)
(* SAT solving *) val solver = Unsynchronized.ref"auto"; fun sat_solver x =
Function_Common.PROFILE "sat_solving..." (SAT_Solver.invoke_solver (!solver)) x
(* "Virtual constructors" for various propositional variables *) fun var_constrs (gp as GP (arities, _)) = let val n = Int.max (num_graphs gp, num_prog_pts gp) val k = fold Integer.max arities 1
(* Injective, provided a < 8, x < n, and i < k. *) fun prod a x i j = ((j * k + i) * n + x) * 8 + a + 1
fun ES (g, i, j) = BoolVar (prod 0 g i j) fun EW (g, i, j) = BoolVar (prod 1 g i j) fun WEAK g = BoolVar (prod 2 g 0 0) fun STRICT g = BoolVar (prod 3 g 0 0) fun P (p, i) = BoolVar (prod 4 p i 0) fun GAM (g, i, j)= BoolVar (prod 5 g i j) fun EPS (g, i) = BoolVar (prod 6 g i 0) fun TAG (p, i) b = BoolVar (prod 7 p i b) in
(ES,EW,WEAK,STRICT,P,GAM,EPS,TAG) end
fun graph_info gp g = let val G (p, q, edgs) = graph_at (gp, g) in
(g, p, q, arity gp p, arity gp q, edgs) end
(* Order-independent part of encoding *)
fun encode_graphs bits gp = let val ng = num_graphs gp val (ES,EW,_,_,_,_,_,TAG) = var_constrs gp
fun encode_constraint_strict 0 (x, y) = Prop_Logic.False
| encode_constraint_strict k (x, y) = Or (And (TAG x (k - 1), Not (TAG y (k - 1))), And (Equiv (TAG x (k - 1), TAG y (k - 1)),
encode_constraint_strict (k - 1) (x, y)))
fun encode_constraint_weak k (x, y) = Or (encode_constraint_strict k (x, y),
iforall k (fn i => Equiv (TAG x i, TAG y i)))
fun encode_graph (g, p, q, n, m, edges) = let fun encode_edge i j = ifexists (fn x => x = (i, GTR, j)) edges then And (ES (g, i, j), EW (g, i, j)) elseifnot (exists (fn x => x = (i, GEQ, j)) edges) then And (Not (ES (g, i, j)), Not (EW (g, i, j))) else And (
Equiv (ES (g, i, j),
encode_constraint_strict bits ((p, i), (q, j))),
Equiv (EW (g, i, j),
encode_constraint_weak bits ((p, i), (q, j)))) in
iforall2 n m encode_edge end in
iforall ng (encode_graph o graph_info gp) end
(* Order-specific part of encoding *)
fun encode bits gp mu = let val ng = num_graphs gp val (ES,EW,WEAK,STRICT,P,GAM,EPS,_) = var_constrs gp
fun encode_graph MAX (g, p, q, n, m, _) = And (
Equiv (WEAK g,
iforall m (fn j =>
Implies (P (q, j),
iexists n (fn i => And (P (p, i), EW (g, i, j)))))),
Equiv (STRICT g, And (
iforall m (fn j =>
Implies (P (q, j),
iexists n (fn i => And (P (p, i), ES (g, i, j))))),
iexists n (fn i => P (p, i)))))
| encode_graph MIN (g, p, q, n, m, _) = And (
Equiv (WEAK g,
iforall n (fn i =>
Implies (P (p, i),
iexists m (fn j => And (P (q, j), EW (g, i, j)))))),
Equiv (STRICT g, And (
iforall n (fn i =>
Implies (P (p, i),
iexists m (fn j => And (P (q, j), ES (g, i, j))))),
iexists m (fn j => P (q, j)))))
| encode_graph MS (g, p, q, n, m, _) = all [
Equiv (WEAK g,
iforall m (fn j =>
Implies (P (q, j),
iexists n (fn i => GAM (g, i, j))))),
Equiv (STRICT g,
iexists n (fn i => And (P (p, i), Not (EPS (g, i))))),
iforall2 n m (fn i => fn j =>
Implies (GAM (g, i, j), all [
P (p, i),
P (q, j),
EW (g, i, j),
Equiv (Not (EPS (g, i)), ES (g, i, j))])),
iforall n (fn i =>
Implies (And (P (p, i), EPS (g, i)),
exactly_one m (fn j => GAM (g, i, j))))
] in all [
encode_graphs bits gp,
iforall ng (encode_graph mu o graph_info gp),
iforall ng (fn x => WEAK x),
iexists ng (fn x => STRICT x)
] end
(*Generieren des level-mapping und diverser output*) fun mk_certificate bits label gp f = let val (ES,EW,WEAK,STRICT,P,GAM,EPS,TAG) = var_constrs gp fun assign (Prop_Logic.BoolVar v) = the_default false (f v) fun assignTag i j =
(fold (fn x => fn y => 2 * y + (if assign (TAG (i, j) x) then 1 else 0))
(bits - 1 downto 0) 0)
val level_mapping = letfun prog_pt_mapping p =
map_filter (fn x => if assign (P(p, x)) then SOME (x, assignTag p x) else NONE)
(0 upto (arity gp p) - 1) in map_range prog_pt_mapping (num_prog_pts gp) end
val strict_list = filter (assign o STRICT) (0 upto num_graphs gp - 1)
fun covering_pair g bStrict j = let val (_, p, q, n, m, _) = graph_info gp g
fun cover MAX j = find_index (fn i => assign (P (p, i)) andalso assign (EW (g, i, j))) (0 upto n - 1)
| cover MS k = find_index (fn i => assign (GAM (g, i, k))) (0 upto n - 1)
| cover MIN i = find_index (fn j => assign (P (q, j)) andalso assign (EW (g, i, j))) (0 upto m - 1) fun cover_strict MAX j = find_index (fn i => assign (P (p, i)) andalso assign (ES (g, i, j))) (0 upto n - 1)
| cover_strict MS k = find_index (fn i => assign (GAM (g, i, k)) andalso not (assign (EPS (g, i) ))) (0 upto n - 1)
| cover_strict MIN i = find_index (fn j => assign (P (q, j)) andalso assign (ES (g, i, j))) (0 upto m - 1) val i = if bStrict then cover_strict label j else cover label j in
find_first (fn x => fst x = i) (nth level_mapping (if label = MIN then q else p)) end in
(label, level_mapping, strict_list, covering_pair) end
(*interface for the proof reconstruction*) fun generate_certificate use_tags labels gp = let val bits = if use_tags then ndigits gp else 0 in
get_first
(fn l => case sat_solver (encode bits gp l) of
SAT_Solver.SATISFIABLE f => SOME (mk_certificate bits l gp f)
| _ => NONE)
labels end end
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.