needs "../formal_lp/hypermap/list_hypermap.hl";;
needs "../formal_lp/hypermap/list_hypermap_iso.hl";;
needs "../formal_lp/hypermap/constants_approx.hl";;
needs "arith/nat.hl";;
needs "misc/vars.hl";;
open Constant_approximations;;
open Misc_vars;;
open Sphere;;
(* Definitions of variables *)
(* Variables for fans *)
(* TODO: these definitions are not necessary *)
let fan_defs =
[
azim2_fan; azim3_fan; yn_fan; ln_fan; ye_fan;
rho_fan; sol_fan; tau_fan; rhazim_fan; rhazim2_fan; rhazim3_fan;
y1_fan; y2_fan; y3_fan; y4_fan; y5_fan; y6_fan; y8_fan; y9_fan;
]
(* Variables for lists *)
let list_defs = map new_definition
[
`azim_list (V,g) = (azim_dart (V,ESTD V) o g):num#num->real`;
`azim2_list (V,g) = (azim2_fan (V,ESTD V) o g):num#num->real`;
`azim3_list (V,g) = (azim3_fan (V,ESTD V) o g):num#num->real`;
`(yn_list g):(num#num->bool)->real = yn_fan o IMAGE g`;
`(ln_list g):(num#num->bool)->real = ln_fan o IMAGE g`;
`rhazim_list (V,g) = (rhazim_fan (V,ESTD V) o g):num#num->real`;
`rhazim2_list (V,g) = (rhazim2_fan (V,ESTD V) o g):num#num->real`;
`rhazim3_list (V,g) = (rhazim3_fan (V,ESTD V) o g):num#num->real`;
`(ye_list g):(num#num->real) = ye_fan o g`;
`(rho_list g):(num#num->bool)->real = rho_fan o IMAGE g`;
`(sol_list (V,g)):(num#num->bool)->real = sol_fan (V,ESTD V) o IMAGE g`;
`(tau_list (V,g)):(num#num->bool)->real = tau_fan (V,ESTD V) o IMAGE g`;
`(y1_list g):(num#num->real) = y1_fan o g`;
`(y2_list g):(num#num->real) = y2_fan o g`;
`(y3_list (V,g)):(num#num->real) = y3_fan (V,ESTD V) o g`;
`(y4_list (V,g)):(num#num->real) = y4_fan (V,ESTD V) o g`;
`(y5_list (V,g)):(num#num->real) = y5_fan (V,ESTD V) o g`;
`(y6_list g):(num#num->real) = y6_fan o g`;
`(y8_list (V,g)):(num#num->real) = y8_fan (V,ESTD V) o g`;
`(y9_list (V,g)):(num#num->real) = y9_fan (V,ESTD V) o g`;
];;
let list_defs2 = map (REWRITE_RULE[FUN_EQ_THM; o_THM]) list_defs;;
let list_var_rewrites =
map GSYM list_defs @ map GSYM list_defs2;;
(* All variables are nonnegative *)
let list_var_pos = map (fun tm -> prove(tm,
GEN_TAC THEN REWRITE_TAC list_defs2 THEN REWRITE_TAC fan_defs THEN
TRY (MATCH_MP_TAC REAL_LE_MUL) THEN
REWRITE_TAC[AZIM_DART_POS; REAL_ABS_POS; NORM_POS_LE; DIST_POS]))
[
`!x. &0 <= azim_list (V,g) x`;
`!x. &0 <= azim2_list (V,g) x`;
`!x. &0 <= azim3_list (V,g) x`;
`!x. &0 <= rhazim_list (V,g) x`;
`!x. &0 <= rhazim2_list (V,g) x`;
`!x. &0 <= rhazim3_list (V,g) x`;
`!n. &0 <= yn_list g n`;
`!n. &0 <= ln_list g n`;
`!e. &0 <= ye_list g e`;
`!n. &0 <= rho_list g n`;
`!f. &0 <= sol_list (V,g) f`;
`!f. &0 <= tau_list (V,g) f`;
`!x. &0 <= y1_list g x`;
`!x. &0 <= y2_list g x`;
`!x. &0 <= y3_list (V,g) x`;
`!x. &0 <= y4_list (V,g) x`;
`!x. &0 <= y5_list (V,g) x`;
`!x. &0 <= y6_list g x`;
`!x. &0 <= y8_list (V,g) x`;
`!x. &0 <= y9_list (V,g) x`;
];;
(* mod-file variables and definitions *)
let var_bound_ineqs = Hashtbl.create 40;;
let sets =
["dart", `dart H:A->bool`;
"dart3", `hyp_dart3 H:A->bool`;
"node", `node_set H:(A->bool)->bool`;
"face", `face_set H:(A->bool)->bool`;
"dart_std4", `hyp_dart4 H:A->bool`];;
let define_var var_name set_name low high =
let var = match set_name with
"dart" | "dart3" | "dart_std4" -> `d:A`
| "node" -> `n:A->bool`
| "face" -> `f:A->bool`
| _ -> failwith "Undefined set name" in
let var_ty = snd (dest_var var) in
let f_ty = mk_type ("fun", [var_ty; `:real`]) in
let set_ty = mk_type ("fun", [var_ty; `:bool`]) in
let f = mk_var (var_name^"_mod", f_ty) in
let set = assoc set_name sets in
let in_const = mk_mconst ("IN", mk_type ("fun", [var_ty; mk_type ("fun", [set_ty; `:bool`])])) in
let le = `(<=):real->real->bool` in
let fvar = mk_comb (f, var) in
let l, h = mk_binop le low fvar, mk_binop le fvar high in
let cond = mk_binop in_const var set in
let ineq_lo = mk_forall(var, mk_imp(cond, l)) in
let ineq_hi = mk_forall(var, mk_imp(cond, h)) in
let _ = Hashtbl.add var_bound_ineqs (var_name^"_lo") ineq_lo in
let _ = Hashtbl.add var_bound_ineqs (var_name^"_hi") ineq_hi in
f;;
(* Terms for variables in the model file *)
Hashtbl.clear var_bound_ineqs;;
let azim_mod = define_var "azim" "dart" `&0` `pi` and
azim2_mod = define_var "azim2" "dart3" `&0` `pi` and
azim3_mod = define_var "azim3" "dart3" `&0` `pi` and
ln_mod = define_var "ln" "node" `&0` `&1` and
rhazim_mod = define_var "rhazim" "dart" `&0` `pi + sol0` and
rhazim2_mod = define_var "rhazim2" "dart3" `&0` `pi + sol0` and
rhazim3_mod = define_var "rhazim3" "dart3" `&0` `pi + sol0` and
yn_mod = define_var "yn" "node" `&2` `#2.52`and
ye_mod = define_var "ye" "dart" `&2` `&3` and
rho_mod = define_var "rho" "node" `&1` `&1 + sol0 / pi` and
sol_mod = define_var "sol" "face" `&0` `&4 * pi` and
tau_mod = define_var "tau" "face" `&0` `tgt` and
y1_mod = define_var "y1" "dart" `&2` `#2.52` and
y2_mod = define_var "y2" "dart" `&2` `#2.52` and
y3_mod = define_var "y3" "dart" `&2` `#2.52` and
y4_mod = define_var "y4" "dart3" `&2` `&3` and
y5_mod = define_var "y5" "dart" `&2` `&3` and
y6_mod = define_var "y6" "dart" `&2` `&3` and
y8_mod = define_var "y8" "dart_std4" `&2` `#2.52` and
y9_mod = define_var "y9" "dart_std4" `&2` `#2.52`;;
let var_list =
let inst_t = inst[`:real^3#real^3`, aty] in
[
`hypermap_of_fan (V,E)`, `H:(real^3#real^3)hypermap`;
`azim_dart (V,E)`, inst_t azim_mod;
`azim2_fan (V,E)`, inst_t azim2_mod;
`azim3_fan (V,E)`, inst_t azim3_mod;
`ln_fan`, inst_t ln_mod;
`rhazim_fan (V,E)`, inst_t rhazim_mod;
`rhazim2_fan (V,E)`, inst_t rhazim2_mod;
`rhazim3_fan (V,E)`, inst_t rhazim3_mod;
`yn_fan`, inst_t yn_mod;
`ye_fan`, inst_t ye_mod;
`rho_fan`, inst_t rho_mod;
`sol_fan (V,E)`, inst_t sol_mod;
`tau_fan (V,E)`, inst_t tau_mod;
`y1_fan`, inst_t y1_mod;
`y2_fan`, inst_t y2_mod;
`y3_fan (V,E)`, inst_t y3_mod;
`y4_fan (V,E)`, inst_t y4_mod;
`y5_fan (V,E)`, inst_t y5_mod;
`y6_fan`, inst_t y6_mod;
`y8_fan (V,E)`, inst_t y8_mod;
`y9_fan (V,E)`, inst_t y9_mod;
];;
(* Declare all inequalities in a format which is close to the mod-file format *)
let constraints = Hashtbl.create 100;;
let add_constraints = map (uncurry (Hashtbl.add constraints));;
(* equality constraints *)
add_constraints
[
"azim_sum", `!n. n IN node_set (H:(A)hypermap) ==> sum n azim_mod = &2 * pi`;
"rhazim_sum", `!n. n IN node_set (H:(A)hypermap) ==> sum n rhazim_mod = &2 * pi * rho_mod n`;
"sol_sum3", `!f. f IN hyp_face3 (H:(A)hypermap) ==> sum f azim_mod = sol_mod f + pi`;
"tau_sum3", `!f. f IN hyp_face3 (H:(A)hypermap) ==> sum f rhazim_mod = tau_mod f + (pi + sol0)`;
"sol_sum4", `!f. f IN hyp_face4 (H:(A)hypermap) ==> sum f azim_mod = sol_mod f + &2 * pi`;
"tau_sum4", `!f. f IN hyp_face4 (H:(A)hypermap) ==> sum f rhazim_mod = tau_mod f + &2 * (pi + sol0)`;
"sol_sum5", `!f. f IN hyp_face5 (H:(A)hypermap) ==> sum f azim_mod = sol_mod f + &3 * pi`;
"tau_sum5", `!f. f IN hyp_face5 (H:(A)hypermap) ==> sum f rhazim_mod = tau_mod f + &3 * (pi + sol0)`;
"sol_sum6", `!f. f IN hyp_face6 (H:(A)hypermap) ==> sum f azim_mod = sol_mod f + &4 * pi`;
"tau_sum6", `!f. f IN hyp_face6 (H:(A)hypermap) ==> sum f rhazim_mod = tau_mod f + &4 * (pi + sol0)`;
"ln_def", `!n. n IN node_set (H:(A)hypermap) ==> ln_mod n = (#2.52 - yn_mod n) / #0.52`;
"rho_def", `!n. n IN node_set (H:(A)hypermap) ==> rho_mod n = (&1 + sol0 / pi) - ln_mod n * sol0 / pi`;
"edge_sym", `!e. e IN hyp_edge_pairs (H:(A)hypermap) ==> ye_mod (FST e) = ye_mod (SND e):real`;
"y1_def", `!d. d IN dart (H:(A)hypermap) ==> y1_mod d = yn_mod (node H d):real`;
"y2_def", `!d. d IN dart (H:(A)hypermap) ==> y2_mod d = yn_mod (node H (face_map H d)):real`;
"y3_def", `!d. d IN dart (H:(A)hypermap) ==> y3_mod d = yn_mod (node H (inverse (face_map H) d)):real`;
"y4_def", `!d. d IN hyp_dart3 (H:(A)hypermap) ==> y4_mod d = ye_mod (face_map H d):real`;
"y5_def", `!d. d IN dart (H:(A)hypermap) ==> y5_mod d = ye_mod (inverse (face_map H) d):real`;
"y6_def", `!d. d IN dart (H:(A)hypermap) ==> y6_mod d = ye_mod d:real`;
"y9_def", `!d. d IN hyp_dart4 (H:(A)hypermap) ==> y9_mod d = ye_mod (face_map H d):real`;
"y8_def", `!d. d IN hyp_dart4 (H:(A)hypermap) ==> y8_mod d = y5_mod (inverse (face_map H) d):real`;
"azim2c", `!d. d IN hyp_dart3 (H:(A)hypermap) ==> azim2_mod d = azim_mod (face_map H d):real`;
"azim3c", `!d. d IN hyp_dart3 (H:(A)hypermap) ==> azim3_mod d = azim_mod (inverse (face_map H) d):real`;
"rhazim2c", `!d. d IN hyp_dart3 (H:(A)hypermap) ==> rhazim2_mod d = rhazim_mod (face_map H d):real`;
"rhazim3c", `!d. d IN hyp_dart3 (H:(A)hypermap) ==> rhazim3_mod d = rhazim_mod (inverse (face_map H) d):real`;
];;
(* inequality constraints *)
add_constraints
[
"RHA", `!d. d IN dart (H:(A)hypermap) ==> rhazim_mod d >= azim_mod d:real`;
"RHB", `!d. d IN dart (H:(A)hypermap) ==> rhazim_mod d <= azim_mod d * (&1 + sol0 / pi)`;
(* "RHBLO"; "RHBHI" *)
];;
(* definitional inequalities *)
(* y bounds *)
add_constraints
[
"yy10", `!d. (d:A) IN dart (H:(A)hypermap) ==> ye_mod d <= #2.52`;
];;
(* tau tame table D inequality (Main Estimate) *)
add_constraints
[
"tau3", `!f:A->bool. f IN hyp_face3 (H:(A)hypermap) ==> tau_mod f >= &0`;
"tau4", `!f:A->bool. f IN hyp_face4 (H:(A)hypermap) ==> tau_mod f >= #0.206`;
"tau5", `!f:A->bool. f IN hyp_face5 (H:(A)hypermap) ==> tau_mod f >= #0.4819`;
"tau6", `!f:A->bool. f IN hyp_face6 (H:(A)hypermap) ==> tau_mod f >= #0.7578`;
];;
add_constraints
[
"ineq105", `!d:A. d IN hyp_dartX H ==>
((((azim_mod d) - #1.629) + ((#0.402 * (y2_mod d +
(y3_mod d + (y5_mod d + (y6_mod d - #8.0))))) -
(#0.315 * (y1_mod d - #2.0)))) - #0.0) >= #0.0`;
"ineq106", `!d:A. d IN hyp_dart3 H ==>
((((rhazim_mod d) - #1.2308) + (((#0.3639 * (y2_mod d + (y3_mod d + (y5_mod d + (y6_mod d - #8.0))))) -
(#0.6 * (y1_mod d - #2.0))) - (#0.685 * (y4_mod d - #2.0)))) - #0.0) >= #0.0`;
"ineq107", `!d:A. d IN hyp_dart3 H ==>
(((--(azim_mod d)) + ((#1.231 - (#0.152 * (y2_mod d + (y3_mod d + (y5_mod d + (y6_mod d - #8.0)))))) + ((#0.5 * (y1_mod d - #2.0)) + (#0.773 * (y4_mod d - #2.0))))) - #0.0) >= #0.0`;
"ineq108", `!d:A. d IN hyp_dart3 H ==>
((((azim_mod d) - #1.2308) + (((#0.3639 * (y2_mod d + (y3_mod d + (y5_mod d + (y6_mod d - #8.0))))) - (#0.235 * (y1_mod d - #2.0))) - (#0.685 * (y4_mod d - #2.0)))) - #0.0) >= #0.0`;
"ineq109", `!d:A. d IN hyp_dart3 H ==>
(((--(sol_mod (face H d))) + (#0.5513 + ((#0.3232 * (y4_mod d + (y5_mod d + (y6_mod d - #6.0)))) - (#0.151 * (y1_mod d + (y2_mod d + (y3_mod d - #6.0))))))) - #0.0) >= #0.0`;
"ineq110", `!d:A. d IN hyp_dart3 H ==>
(((((sol_mod (face H d)) - #0.55125) - (#0.196 * (y4_mod d + (y5_mod d + (y6_mod d - #6.0))))) + (#0.38 * (y1_mod d + (y2_mod d + (y3_mod d - #6.0))))) - #0.0) >= #0.0`;
"ineq111", `!d:A. d IN hyp_dart3 H ==>
(((tau_mod (face H d)) + ((#0.001 - (#0.18 * (y1_mod d + (y2_mod d + (y3_mod d - #6.0))))) - (#0.125 * (y4_mod d + (y5_mod d + (y6_mod d - #6.0)))))) - #0.0) >= #0.0`;
"ineq112", `!d:A. d IN hyp_dart3 H ==>
((((tau_mod (face H d)) - (#0.507 * (azim_mod d))) + #0.724) - #0.0) >= #0.0`;
"ineq113", `!d:A. d IN hyp_dart3 H ==>
((((tau_mod (face H d)) - (#0.259 * (azim_mod d))) + #0.32) - #0.0) >= #0.0`;
"ineq114", `!d:A. d IN hyp_dart3 H ==>
(((tau_mod (face H d)) + ((#0.626 * (azim_mod d)) - #0.77)) - #0.0) >= #0.0`;
"ineq115", `!d:A. d IN hyp_dart3 H ==>
(#1.893 - (azim_mod d)) >= #0.0`;
"ineq116", `!d:A. d IN hyp_dart3 H ==>
((azim_mod d) - #0.852) >= #0.0`;
"ineq119", `!d:A. d IN hyp_dart4 H ==>
((((tau_mod (face H d)) - (#0.453 * (azim_mod d))) + #0.777) - #0.0) >= #0.0`;
"ineq120", `!d:A. d IN hyp_dart4 H ==>
(((tau_mod (face H d)) + ((#0.7573 * (azim_mod d)) - #1.433)) - #0.0) >= #0.0`;
"ineq121", `!d:A. d IN hyp_dart4 H ==>
(((tau_mod (face H d)) + ((#0.972 * (azim_mod d)) - #1.707)) - #0.0) >= #0.0`;
"ineq122", `!d:A. d IN hyp_dart4 H ==>
(((tau_mod (face H d)) + ((#4.72 * (azim_mod d)) - #6.248)) - #0.0) >= #0.0`;
];;
(*
let y1_def = `!d. d IN dart (H:(A)hypermap) ==> y1_mod d = yn_mod (node H d):real`;;
y1_def{(i3,i1,i2,j) in e_dart}: y1[i1,j] = yn[i1];
(* Rename terms and types *)
let s1 = inst [`:real^3#real^3`, aty] im_sum;;
let s2 = subst [`hypermap_of_fan (V,E)`, h_fan_hyp] s1;;
let s3 = subst [`azim_dart (V,E)`, azim_mod] s2;;
*)
(*************************************)
let SUM_ISOMORPHISM = prove(`!G H (g:B->A) (r:A->
real). isomorphism g (G,H)
==> (!d. d
IN dart G ==>
sum(node G d) (r o g) =
sum(node H (g d)) r)`,
REPEAT STRIP_TAC THEN
SUBGOAL_THEN `
sum(node G d) (r o (g:B->A)) =
sum(
IMAGE g (node G d)) r` (fun
th -> REWRITE_TAC[
th]) THENL
[
MATCH_MP_TAC (GSYM
SUM_IMAGE) THEN
REPEAT STRIP_TAC THEN
UNDISCH_TAC `isomorphism (g:B->A) (G,H)` THEN
REWRITE_TAC[isomorphism;
BIJ;
INJ] THEN
DISCH_THEN (MP_TAC o CONJUNCT1) THEN
DISCH_THEN (MP_TAC o CONJUNCT1) THEN
DISCH_THEN (MATCH_MP_TAC o CONJUNCT2) THEN
ASM_REWRITE_TAC[] THEN
CONJ_TAC THEN MATCH_MP_TAC
IN_TRANS THEN EXISTS_TAC `node G (d:B)` THEN ASM_SIMP_TAC[Hypermap.lemma_node_subset];
ALL_TAC
] THEN
MP_TAC (ISPECL [`g:B->A`; `G:(B)hypermap`; `H:(A)hypermap`; `d:B`]
ISOMORPHISM_COMPONENT_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[GSYM
th]));;
let ISO_NODE_INJ = prove(`!G H (g:B->A) n. isomorphism g (G,H) /\ n
IN node_set G ==>
(!x y. x
IN n /\ y
IN n /\ g x = g y ==> x = y)`,
REPEAT STRIP_TAC THEN
UNDISCH_TAC `isomorphism (g:B->A) (G,H)` THEN
REWRITE_TAC[isomorphism;
BIJ;
INJ] THEN
DISCH_THEN (MP_TAC o CONJUNCT1) THEN DISCH_THEN (MP_TAC o CONJUNCT1) THEN
DISCH_THEN (MATCH_MP_TAC o CONJUNCT2) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `n:B->bool`] Hypermap.lemma_node_representation) THEN
ASM_REWRITE_TAC[] THEN
STRIP_TAC THEN
CONJ_TAC THEN MATCH_MP_TAC
IN_TRANS THEN
EXISTS_TAC `n:B->bool` THEN
ASM_REWRITE_TAC[] THEN
ASM_SIMP_TAC[Hypermap.lemma_node_subset]);;
let COMPONENTS_ISO_IMAGE = prove(`!G H (g:B->A). isomorphism g (G,H)
==> (!d. d
IN dart G ==>
node H (g d) =
IMAGE g (node G d) /\
face H (g d) =
IMAGE g (face G d))`,
REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN DISCH_TAC THEN
MP_TAC (ISPECL[`g:B->A`; `G:(B)hypermap`; `H:(A)hypermap`; `d:B`]
ISOMORPHISM_COMPONENT_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
SIMP_TAC[]);;
let HYPERMAP_INV_MAPS = prove(`!(G:(B)hypermap) d. d
IN dart G
==> (?k.
inverse (
face_map G) d = (
face_map G
POWER k) d)`,
REPEAT STRIP_TAC THEN
ABBREV_TAC `n =
CARD (
orbit_map (
face_map G) (d:B))` THEN
MP_TAC (ISPECL [`
face_map G:B->B`; `dart G:B->bool`; `d:B`; `n:num`; `1`] Hypermap_and_fan.FINITE_ORBIT_MAP_INVERSE) THEN
ASM_REWRITE_TAC[Hypermap.hypermap_lemma] THEN
ANTS_TAC THENL
[
REWRITE_TAC[ARITH_RULE `1 <= n <=> 0 < n`] THEN
EXPAND_TAC "n" THEN
MATCH_MP_TAC Hypermap_and_fan.ORBIT_MAP_CARD_POS THEN
EXISTS_TAC `dart G:B->bool` THEN
REWRITE_TAC[Hypermap.hypermap_lemma];
ALL_TAC
] THEN
REWRITE_TAC[Hypermap.POWER_1] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN
EXISTS_TAC `n - 1` THEN
REWRITE_TAC[]);;
let CARD_NODE_ISO = prove(`!G H (g:B->A). isomorphism g (G,H)
==> (!n. n
IN node_set G ==>
CARD (
IMAGE g n) =
CARD n)`,
REPEAT STRIP_TAC THEN
MATCH_MP_TAC
CARD_IMAGE_INJ THEN
CONJ_TAC THENL
[
MATCH_MP_TAC
ISO_NODE_INJ THEN
MAP_EVERY EXISTS_TAC [`G:(B)hypermap`; `H:(A)hypermap`] THEN
ASM_REWRITE_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `n:B->bool`] Hypermap.lemma_node_representation) THEN
ASM_REWRITE_TAC[] THEN
STRIP_TAC THEN
ASM_REWRITE_TAC[Hypermap.NODE_FINITE]);;
let SUM_NODE_SUB = prove(`!(G:(B)hypermap) r1 r2 n. n
IN node_set G
==>
sum n (\x. r1 x - r2 x) =
sum n r1 -
sum n r2`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `n:B->bool`] Hypermap.lemma_node_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
ASM_SIMP_TAC[Hypermap.NODE_FINITE;
SUM_SUB]);;
let SUM_NODE_CONST = prove(`!(G:(B)hypermap) c n. n
IN node_set G
==>
sum n (\x. c) = &(
CARD n) * c`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `n:B->bool`] Hypermap.lemma_node_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
ASM_SIMP_TAC[Hypermap.NODE_FINITE;
SUM_CONST]);;
let ISO_FACE_INJ = prove(`!G H (g:B->A) f. isomorphism g (G,H) /\ f
IN face_set G ==>
(!x y. x
IN f /\ y
IN f /\ g x = g y ==> x = y)`,
REPEAT STRIP_TAC THEN
UNDISCH_TAC `isomorphism (g:B->A) (G,H)` THEN
REWRITE_TAC[isomorphism;
BIJ;
INJ] THEN
DISCH_THEN (MP_TAC o CONJUNCT1) THEN DISCH_THEN (MP_TAC o CONJUNCT1) THEN
DISCH_THEN (MATCH_MP_TAC o CONJUNCT2) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN
STRIP_TAC THEN
CONJ_TAC THEN MATCH_MP_TAC
IN_TRANS THEN
EXISTS_TAC `f:B->bool` THEN
ASM_REWRITE_TAC[] THEN
ASM_SIMP_TAC[Hypermap.lemma_face_subset]);;
let CARD_FACE_ISO = prove(`!G H (g:B->A). isomorphism g (G,H)
==> (!f. f
IN face_set G ==>
CARD (
IMAGE g f) =
CARD f)`,
REPEAT STRIP_TAC THEN
MATCH_MP_TAC
CARD_IMAGE_INJ THEN
CONJ_TAC THENL
[
MATCH_MP_TAC
ISO_FACE_INJ THEN
MAP_EVERY EXISTS_TAC [`G:(B)hypermap`; `H:(A)hypermap`] THEN
ASM_REWRITE_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN
STRIP_TAC THEN
ASM_REWRITE_TAC[Hypermap.FACE_FINITE]);;
let SUM_FACE_SUB = prove(`!(G:(B)hypermap) r1 r2 f. f
IN face_set G
==>
sum f (\x. r1 x - r2 x) =
sum f r1 -
sum f r2`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
ASM_SIMP_TAC[Hypermap.FACE_FINITE;
SUM_SUB]);;
let SUM_FACE_CONST = prove(`!(G:(B)hypermap) c f. f
IN face_set G
==>
sum f (\x. c) = &(
CARD f) * c`,
REPEAT STRIP_TAC THEN
MP_TAC (ISPECL [`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
ASM_SIMP_TAC[Hypermap.FACE_FINITE;
SUM_CONST]);;
let IN_DART3_IMP_IN_DART = UNDISCH_ALL (prove(`d:B IN hyp_dart3 G ==> d IN dart G`,
SIMP_TAC[hyp_dart3; IN_ELIM_THM]));;
let IN_DART4_IMP_IN_DART = UNDISCH_ALL (prove(`d:B IN hyp_dart4 G ==> d IN dart G`,
SIMP_TAC[hyp_dart4; IN_ELIM_THM]));;
let IN_FACE3_IMP_IN_FACE = UNDISCH_ALL (prove(`f IN hyp_face3 (G:(B)hypermap) ==> f IN face_set G`,
SIMP_TAC[hyp_face3; IN_ELIM_THM]));;
let IN_FACE4_IMP_IN_FACE = UNDISCH_ALL (prove(`f IN hyp_face4 (G:(B)hypermap) ==> f IN face_set G`,
SIMP_TAC[hyp_face4; IN_ELIM_THM]));;
let IN_FACE5_IMP_IN_FACE = UNDISCH_ALL (prove(`f IN hyp_face5 (G:(B)hypermap) ==> f IN face_set G`,
SIMP_TAC[hyp_face5; IN_ELIM_THM]));;
let IN_FACE6_IMP_IN_FACE = UNDISCH_ALL (prove(`f IN hyp_face6 (G:(B)hypermap) ==> f IN face_set G`,
SIMP_TAC[hyp_face6; IN_ELIM_THM]));;
(*******************************)
let in_all_rewrites =
[
SUM_NODE_LIST_ALL;
SUM_FACE_LIST_ALL;
EDGE_LIST_ALL;
DART_LIST_ALL;
DART3_LIST_ALL;
DART4_LIST_ALL;
DARTX_LIST_ALL;
FACE3_LIST_ALL;
FACE4_LIST_ALL;
FACE5_LIST_ALL;
FACE6_LIST_ALL;
];;
let table_set_hyp =
let table = Hashtbl.create 10 in
let _ = map (uncurry (Hashtbl.add table))
[
`hyp_dart3 (G:(B)hypermap)`, IN_DART3_IMP_IN_DART;
`hyp_dart4 (G:(B)hypermap)`, IN_DART4_IMP_IN_DART;
`hyp_face3 (G:(B)hypermap)`, IN_FACE3_IMP_IN_FACE;
`hyp_face4 (G:(B)hypermap)`, IN_FACE4_IMP_IN_FACE;
`hyp_face5 (G:(B)hypermap)`, IN_FACE5_IMP_IN_FACE;
`hyp_face6 (G:(B)hypermap)`, IN_FACE6_IMP_IN_FACE;
] in
table;;
(*************************************)
let iso_dart_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!d. d
IN dart H ==> P d) ==> (!d. d
IN dart G ==> P (g d)))`,
REWRITE_TAC[isomorphism;
BIJ;
SURJ] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `d:B`) THEN
FIRST_X_ASSUM (MP_TAC o SPEC `d:B`) THEN
ASM_REWRITE_TAC[] THEN
DISCH_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `(g:B->A) d`) THEN
ASM_SIMP_TAC[]);;
let iso_dart_in = prove(`!(g:B->A) H G d. isomorphism g (G,H) /\ d
IN dart G ==>
g d
IN dart H`,
REWRITE_TAC[isomorphism;
BIJ;
SURJ;
INJ] THEN
REPEAT STRIP_TAC THEN
ASM_SIMP_TAC[]);;
let iso_card_eq = prove(`!(g:B->A) H G s. isomorphism g (G,H) /\ s
SUBSET dart G
==>
CARD (
IMAGE g s) =
CARD s`,
REWRITE_TAC[isomorphism;
BIJ;
INJ] THEN
REPEAT STRIP_TAC THEN
MATCH_MP_TAC
CARD_IMAGE_INJ THEN
CONJ_TAC THENL
[
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_REWRITE_TAC[] THEN
CONJ_TAC THEN MATCH_MP_TAC
IN_TRANS THEN EXISTS_TAC `s:B->bool` THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
MATCH_MP_TAC
FINITE_SUBSET THEN
EXISTS_TAC `dart G:B->bool` THEN
ASM_REWRITE_TAC[Hypermap.hypermap_lemma]);;
let iso_face_card = prove(`!(g:B->A) H G d. isomorphism g (G,H) /\ d
IN dart G
==>
CARD (face H (g d)) =
CARD (face G d)`,
REPEAT STRIP_TAC THEN
MP_TAC (SPEC_ALL
COMPONENTS_ISO_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (MP_TAC o SPEC `d:B`) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
ASM_REWRITE_TAC[] THEN
MATCH_MP_TAC
iso_card_eq THEN
MAP_EVERY EXISTS_TAC [`H:(A)hypermap`; `G:(B)hypermap`] THEN
ASM_SIMP_TAC[Hypermap.lemma_face_subset]);;
let iso_node_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!n. n
IN node_set H ==> P n) ==> (!n. n
IN node_set G ==> P (
IMAGE g n)))`,
REPEAT STRIP_TAC THEN
POP_ASSUM (MP_TAC o MATCH_MP Hypermap.lemma_node_representation) THEN
STRIP_TAC THEN
MP_TAC (ISPECL [`g:B->A`; `G:(B)hypermap`; `H:(A)hypermap`; `x:B`]
ISOMORPHISM_COMPONENT_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[GSYM
th]) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
REWRITE_TAC[GSYM Hypermap.lemma_in_node_set] THEN
MATCH_MP_TAC
iso_dart_in THEN
EXISTS_TAC `G:(B)hypermap` THEN
ASM_REWRITE_TAC[]);;
let iso_face_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!f. f
IN face_set H ==> P f) ==> (!f. f
IN face_set G ==> P (
IMAGE g f)))`,
REPEAT STRIP_TAC THEN
POP_ASSUM (MP_TAC o MATCH_MP Hypermap.lemma_face_representation) THEN
STRIP_TAC THEN
MP_TAC (ISPECL [`g:B->A`; `G:(B)hypermap`; `H:(A)hypermap`; `x:B`]
ISOMORPHISM_COMPONENT_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[GSYM
th]) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
REWRITE_TAC[GSYM Hypermap.lemma_in_face_set] THEN
MATCH_MP_TAC
iso_dart_in THEN
EXISTS_TAC `G:(B)hypermap` THEN
ASM_REWRITE_TAC[]);;
let iso_face3_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!f. f
IN hyp_face3 H ==> P f) ==> (!f. f
IN hyp_face3 G ==> P (
IMAGE g f)))`,
REWRITE_TAC[
hyp_face3;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (SPECL[`g:B->A`; `H:(A)hypermap`; `G:(B)hypermap`]
iso_face_trans) THEN
ASM_REWRITE_TAC[] THEN
REPEAT DISCH_TAC THEN
CONJ_TAC THENL
[
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`f:B->bool`, `f:B->bool`) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
SIMP_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL[`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
UNDISCH_TAC `
CARD (f:B->bool) = 3` THEN
DISCH_THEN (fun
th -> REWRITE_TAC[SYM
th]) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (SPEC_ALL
COMPONENTS_ISO_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> ASM_SIMP_TAC[GSYM
th]) THEN
MATCH_MP_TAC
iso_face_card THEN
ASM_REWRITE_TAC[]);;
let iso_face4_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!f. f
IN hyp_face4 H ==> P f) ==> (!f. f
IN hyp_face4 G ==> P (
IMAGE g f)))`,
REWRITE_TAC[
hyp_face4;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (SPECL[`g:B->A`; `H:(A)hypermap`; `G:(B)hypermap`]
iso_face_trans) THEN
ASM_REWRITE_TAC[] THEN
REPEAT DISCH_TAC THEN
CONJ_TAC THENL
[
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`f:B->bool`, `f:B->bool`) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
SIMP_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL[`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
UNDISCH_TAC `
CARD (f:B->bool) = 4` THEN
DISCH_THEN (fun
th -> REWRITE_TAC[SYM
th]) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (SPEC_ALL
COMPONENTS_ISO_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> ASM_SIMP_TAC[GSYM
th]) THEN
MATCH_MP_TAC
iso_face_card THEN
ASM_REWRITE_TAC[]);;
let iso_face5_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!f. f
IN hyp_face5 H ==> P f) ==> (!f. f
IN hyp_face5 G ==> P (
IMAGE g f)))`,
REWRITE_TAC[
hyp_face5;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (SPECL[`g:B->A`; `H:(A)hypermap`; `G:(B)hypermap`]
iso_face_trans) THEN
ASM_REWRITE_TAC[] THEN
REPEAT DISCH_TAC THEN
CONJ_TAC THENL
[
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`f:B->bool`, `f:B->bool`) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
SIMP_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL[`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
UNDISCH_TAC `
CARD (f:B->bool) = 5` THEN
DISCH_THEN (fun
th -> REWRITE_TAC[SYM
th]) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (SPEC_ALL
COMPONENTS_ISO_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> ASM_SIMP_TAC[GSYM
th]) THEN
MATCH_MP_TAC
iso_face_card THEN
ASM_REWRITE_TAC[]);;
let iso_face6_trans = prove(`!(g:B->A) H G P. isomorphism g (G,H) ==>
((!f. f
IN hyp_face6 H ==> P f) ==> (!f. f
IN hyp_face6 G ==> P (
IMAGE g f)))`,
REWRITE_TAC[
hyp_face6;
IN_ELIM_THM] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
MP_TAC (SPECL[`g:B->A`; `H:(A)hypermap`; `G:(B)hypermap`]
iso_face_trans) THEN
ASM_REWRITE_TAC[] THEN
REPEAT DISCH_TAC THEN
CONJ_TAC THENL
[
REMOVE_ASSUM THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`f:B->bool`, `f:B->bool`) THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
SIMP_TAC[];
ALL_TAC
] THEN
MP_TAC (ISPECL[`G:(B)hypermap`; `f:B->bool`] Hypermap.lemma_face_representation) THEN
ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
UNDISCH_TAC `
CARD (f:B->bool) = 6` THEN
DISCH_THEN (fun
th -> REWRITE_TAC[SYM
th]) THEN
ASM_REWRITE_TAC[] THEN
MP_TAC (SPEC_ALL
COMPONENTS_ISO_IMAGE) THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN (fun
th -> ASM_SIMP_TAC[GSYM
th]) THEN
MATCH_MP_TAC
iso_face_card THEN
ASM_REWRITE_TAC[]);;
let iso_trans_table =
let table = Hashtbl.create 10 in
let _ = map (uncurry (Hashtbl.add table))
[
`dart H:A->bool`, iso_dart_trans;
`node_set (H:(A)hypermap)`, iso_node_trans;
`face_set (H:(A)hypermap)`, iso_face_trans;
`hyp_edge_pairs (H:(A)hypermap)`, iso_edge_pairs_trans;
`hyp_dart3 (H:(A)hypermap)`, iso_dart3_trans;
`hyp_dart4 (H:(A)hypermap)`, iso_dart4_trans;
`hyp_dartX (H:(A)hypermap)`, iso_dartX_trans;
`hyp_face3 (H:(A)hypermap)`, iso_face3_trans;
`hyp_face4 (H:(A)hypermap)`, iso_face4_trans;
`hyp_face5 (H:(A)hypermap)`, iso_face5_trans;
`hyp_face6 (H:(A)hypermap)`, iso_face6_trans;
] in
table;;
(**************************)
let gen_iso_thm ineq =
let x_tm, tm = dest_forall ineq in
let set, p_tm' = dest_binary "==>" tm in
let set_th = Hashtbl.find iso_trans_table (rand set) in
let p_tm = mk_abs (x_tm, p_tm') in
let p_var = mk_var ("P", type_of (rand set)) in
let th3 = (SPEC_ALL (REWRITE_RULE[IMP_IMP] set_th)) in
BETA_RULE (INST[p_tm, p_var] th3);;
let gen_general_ineq ineq =
let iso_th = gen_iso_thm ineq in
(* General rewrites before specifying hypermaps *)
let th0 = UNDISCH_ALL (REWRITE_RULE[GSYM IMP_IMP] iso_th) in
let gen_var, rtm = dest_forall(concl th0) in
let ants = lhand rtm in
let set = rand ants in
let th1 = UNDISCH_ALL (SPEC_ALL th0) in
let th_rule th = UNDISCH_ALL (SPEC_ALL (UNDISCH_ALL (SPEC_ALL th))) in
let ths = [
th_rule SUM_NODE_ISO;
th_rule CARD_NODE_ISO;
th_rule SUM_FACE_ISO;
th_rule CARD_FACE_ISO;
th_rule COMPONENTS_ISO_IMAGE;
th_rule HYPERMAP_MAPS_ISO_IMAGE;
th_rule HYPERMAP_INV_MAPS_ISO_IMAGE;
th_rule HYPERMAP_MAPS_ISO_COMM;
th_rule HYPERMAP_INV_MAPS_ISO_COMM;
SUB_CONST_o; ETA_AX;
th_rule SUM_FACE_SUB_CONST;
] in
let th2' = REWRITE_RULE ths th1 in
let th2 =
if (Hashtbl.mem table_set_hyp set) then
PROVE_HYP (Hashtbl.find table_set_hyp set) th2'
else
th2' in
let th3 = GEN gen_var (DISCH ants th2) in
let s0 = th3 in
(* G -> hypermap_of_list (L:((num)list)list) *)
(* Instantiate correct types *)
let s1 = INST_TYPE [`:real^3#real^3`, aty; `:num#num`, bty] s0 in
let s2 = INST[`hypermap_of_list (L:((num)list)list)`, `G:(num#num)hypermap`] s1 in
let th_rule = (UNDISCH_ALL o INST_TYPE [`:num`, aty] o SPEC_ALL o REWRITE_RULE[GSYM IMP_IMP]) in
let ths = map th_rule in_all_rewrites in
let s3 = REWRITE_RULE ths s2 in
let gen_var2, rtm = dest_forall(concl s3) in
let ants2 = lhand rtm in
let s4 = UNDISCH_ALL (SPEC_ALL s3) in
let ths =
[
th_rule CARD_SET_OF_LIST_FACE;
th_rule CARD_SET_OF_LIST_NODE;
] in
let s5 = REWRITE_RULE ths s4 in
let s6 = GEN gen_var2 (DISCH ants2 s5) in
(* Deal with basic variables *)
let s7 = INST var_list s6 in
let s8 = INST[`ESTD V`, `E:(real^3->bool)->bool`] s7 in
let s9 = REWRITE_RULE list_var_rewrites s8 in
let r0 = s9 in
(* Basic rewrites *)
let ths =
[
UNDISCH_ALL (INST_TYPE [`:num`, aty] (SPEC_ALL COMPONENTS_HYPERMAP_OF_LIST));
] in
let r1 = REWRITE_RULE ths r0 in
(* Further rewrites *)
let r2 = REWRITE_RULE[darts_of_list; IN_SET_OF_LIST; ALL_MEM] r1 in
r2;;
(***********************)
(*
let get_ineq str = Hashtbl.find constraints str;;
let th = gen_general_ineq (get_ineq "ineq122");;
let th = gen_general_ineq (get_ineq "sol_sum3");;
let th = gen_general_ineq (get_ineq "tau_sum");;
let th = gen_general_ineq (get_ineq "edge_sym");;
let th = gen_general_ineq (get_ineq "ln_def");;
let th = gen_general_ineq (get_ineq "y1_def");;
let th = gen_general_ineq (get_ineq "y2_def");;
let th = gen_general_ineq (get_ineq "y3_def");;
let th = gen_general_ineq (get_ineq "y4_def");;
let th = gen_general_ineq (get_ineq "y5_def");;
let th = gen_general_ineq (get_ineq "y6_def");;
let th = gen_general_ineq (get_ineq "y8_def");;
let th = gen_general_ineq (get_ineq "y9_def");;
let th = gen_general_ineq (get_ineq "RHB");;
let test_list = ref [];;
let iter_f name ineq =
try
test_list := gen_general_ineq ineq :: !test_list
with x ->
print_string ("problems: "^name^"; ");;
Hashtbl.iter iter_f constraints;;
(********************************)
let ineq = get_ineq "tau_sum3";;
let iso_th = gen_iso_thm ineq;;
(* General rewrites before specifying hypermaps *)
let th0 = UNDISCH_ALL (REWRITE_RULE[GSYM IMP_IMP] iso_th);;
let gen_var, rtm = dest_forall(concl th0);;
let ants = lhand rtm;;
let set = rand ants;;
let th1 = UNDISCH_ALL (SPEC_ALL th0);;
let th_rule th = UNDISCH_ALL (SPEC_ALL (UNDISCH_ALL (SPEC_ALL th)));;
let ths = [
th_rule SUM_NODE_ISO;
th_rule CARD_NODE_ISO;
th_rule SUM_FACE_ISO;
th_rule CARD_FACE_ISO;
th_rule COMPONENTS_ISO_IMAGE;
th_rule HYPERMAP_MAPS_ISO_IMAGE;
th_rule HYPERMAP_INV_MAPS_ISO_IMAGE;
th_rule HYPERMAP_MAPS_ISO_COMM;
th_rule HYPERMAP_INV_MAPS_ISO_COMM;
SUB_CONST_o; ETA_AX;
th_rule SUM_FACE_SUB_CONST;
];;
let th2' = REWRITE_RULE ths th1;;
let th2 =
if (Hashtbl.mem table_set_hyp set) then
PROVE_HYP (Hashtbl.find table_set_hyp set) th2'
else
th2';;
let th3 = GEN gen_var (DISCH ants th2);;
let s0 = th3;;
(* G -> hypermap_of_list (L:((num)list)list) *)
(* Instantiate correct types *)
let s1 = INST_TYPE [`:real^3#real^3`, aty; `:num#num`, bty] s0;;
let s2 = INST[`hypermap_of_list (L:((num)list)list)`, `G:(num#num)hypermap`] s1;;
let th_rule = (UNDISCH_ALL o INST_TYPE [`:num`, aty] o SPEC_ALL o REWRITE_RULE[GSYM IMP_IMP]);;
let ths = map th_rule in_all_rewrites;;
let s3 = REWRITE_RULE ths s2;;
let gen_var2, rtm = dest_forall(concl s3);;
let ants2 = lhand rtm;;
let s4 = UNDISCH_ALL (SPEC_ALL s3);;
let ths =
[
th_rule CARD_SET_OF_LIST_FACE;
th_rule CARD_SET_OF_LIST_NODE;
];;
let s5 = REWRITE_RULE ths s4;;
let s6 = GEN gen_var2 (DISCH ants2 s5);;
(* Deal with basic variables *)
let s7 = INST var_list s6;;
let s8 = INST[`ESTD V`, `E:(real^3->bool)->bool`] s7;;
let s9 = REWRITE_RULE list_var_rewrites s8;;
let r0 = s9;;
(* Basic rewrites *)
let ths =
[
UNDISCH_ALL (INST_TYPE [`:num`, aty] (SPEC_ALL COMPONENTS_HYPERMAP_OF_LIST));
];;
let r1 = REWRITE_RULE ths r0;;
(* Further rewrites *)
let r2 = REWRITE_RULE[darts_of_list; IN_SET_OF_LIST; ALL_MEM] r1
r2;;
*)
(*********************************************************)
(* Integral approximation of inequalities and equalities *)
let mk_decimal (n,m) =
let tm = mk_comb(mk_comb(`DECIMAL`, mk_numeral (abs_num n)), mk_numeral m) in
if (n </ Int 0) then mk_comb(neg_op_real, tm) else tm;;
(*
Given a rational number term `r` and a natural number k,
returns a pair of theorems:
|- low <= r, |- r <= high,
with decimal low and high such that
|low - r| <= 10^(-k) and |high - r| <= 10^(-k)
*)
let real_rat_approx tm precision =
let n = rat_of_term tm in
let m = Int 10 **/ (Int precision) in
let n1 = n */ m in
let low, high = floor_num n1, ceiling_num n1 in
let l_tm, h_tm =
if precision = 0 then
term_of_rat low, term_of_rat high
else
mk_decimal (low, m), mk_decimal (high, m) in
let l_th = EQT_ELIM (REAL_RAT_LE_CONV (mk_binop le_op_real l_tm tm)) in
let h_th = EQT_ELIM (REAL_RAT_LE_CONV (mk_binop le_op_real tm h_tm)) in
l_th, h_th;;
(* Split a sum into two parts: with and without free variables *)
let sum_th0 = REAL_ARITH `x = x + &0 + &0` and
sum_th1 = REAL_ARITH `(x + y) + b + c = y + (x + b) + c:real` and
sum_th2 = REAL_ARITH `(x + y) + b + c = y + b + (x + c):real` and
sum_th1' = REAL_ARITH `x + b + c = (x + b) + c:real` and
sum_th2' = REAL_ARITH `x + b + c = b + (x + c):real`;;
let c_var_real = `c:real`;;
let split_sum_conv tm =
let rec split_sum_raw_conv tm =
let xy_tm, bc_tm = dest_binop add_op_real tm in
let b_tm, c_tm = dest_binop add_op_real bc_tm in
if (is_binop add_op_real xy_tm) then
let x_tm, y_tm = dest_binop add_op_real xy_tm in
let inst_th = INST[x_tm, x_var_real; y_tm, y_var_real; b_tm, b_var_real; c_tm, c_var_real] in
let th1 = if (frees x_tm <> []) then inst_th sum_th1 else inst_th sum_th2 in
let th2 = split_sum_raw_conv (rand(concl th1)) in
TRANS th1 th2
else
let inst_th = INST[xy_tm, x_var_real; b_tm, b_var_real; c_tm, c_var_real] in
if (frees xy_tm <> []) then inst_th sum_th1' else inst_th sum_th2' in
let th0 = INST[tm, x_var_real] sum_th0 in
let th1 = split_sum_raw_conv (rand(concl th0)) in
TRANS th0 th1;;
let rearrange_mul_conv tm =
let rec dest_mul tm =
if (is_binop mul_op_real tm) then
let lhs, rhs = dest_binop mul_op_real tm in
let cs, vars = dest_mul rhs in
if (frees lhs = []) then
lhs::cs, vars
else
cs, lhs::vars
else
if (frees tm = []) then
[tm], []
else
[], [tm] in
let mk_mul list =
if (list = []) then failwith "rearrange_mul: empty list"
else itlist (fun l r -> mk_binop mul_op_real l r) (tl list) (hd list) in
let cs, vars = dest_mul tm in
let cs_mul, vars_mul = mk_mul cs, mk_mul vars in
let t = mk_eq(tm, mk_binop mul_op_real cs_mul vars_mul) in
EQT_ELIM (REWRITE_CONV[REAL_MUL_AC] t);;
let le_add_th = REAL_ARITH `x + y <= b + c <=> x - b <= c - y:real`;;
(* Moves everything with free variables on the left and performs basic reductions *)
let ineq_rewrite_conv = REWRITE_CONV[real_ge; real_div; DECIMAL] THENC
LAND_CONV REAL_POLY_CONV THENC RAND_CONV REAL_POLY_CONV THENC
LAND_CONV split_sum_conv THENC RAND_CONV split_sum_conv THENC
ONCE_REWRITE_CONV[le_add_th] THENC
LAND_CONV REAL_POLY_CONV THENC RAND_CONV REAL_POLY_CONV THENC
REWRITE_CONV[GSYM real_div] THENC
ONCE_DEPTH_CONV rearrange_mul_conv;;
(* Approximation *)
let le_mul1_th = REAL_ARITH `!x. &1 * x <= x`;;
let ge_mul1_th = REAL_ARITH `!x. x <= &1 * x`;;
let rec low_approx tm precision =
let low_approx1 tm precision =
if (is_binop mul_op_real tm && frees tm <> []) then
let c, var = dest_binop mul_op_real tm in
let interval_th = approx_interval (create_interval c) precision in
let l_th = MATCH_MP INTERVAL_LO interval_th in
let a, b = dest_binop le_op_real (concl l_th) in
(PROVE_HYP l_th o UNDISCH_ALL o REWRITE_RULE[GSYM IMP_IMP] o SPECL[a; b; var]) REAL_LE_RMUL
else
if (frees tm = []) then
MATCH_MP INTERVAL_LO (approx_interval (create_interval tm) precision)
else
SPEC tm le_mul1_th in
if (is_binop add_op_real tm && frees tm <> []) then
let lhs, rhs = dest_binop add_op_real tm in
let l_th = low_approx1 lhs precision in
let r_th = low_approx rhs precision in
MATCH_MP REAL_LE_ADD2 (CONJ l_th r_th)
else
low_approx1 tm precision;;
let rec hi_approx tm precision =
let hi_approx1 tm precision =
if (is_binop mul_op_real tm && frees tm <> []) then
let c, var = dest_binop mul_op_real tm in
let interval_th = approx_interval (create_interval c) precision in
let h_th = MATCH_MP INTERVAL_HI interval_th in
let a, b = dest_binop le_op_real (concl h_th) in
(PROVE_HYP h_th o UNDISCH_ALL o REWRITE_RULE[GSYM IMP_IMP] o SPECL[a; b; var]) REAL_LE_RMUL
else
if (frees tm = []) then
MATCH_MP INTERVAL_HI (approx_interval (create_interval tm) precision)
else
SPEC tm ge_mul1_th in
if (is_binop add_op_real tm && frees tm <> []) then
let lhs, rhs = dest_binop add_op_real tm in
let l_th = hi_approx1 lhs precision in
let r_th = hi_approx rhs precision in
MATCH_MP REAL_LE_ADD2 (CONJ l_th r_th)
else
hi_approx1 tm precision;;
let approx_le_ineq precision tm =
let lhs, rhs = dest_binop le_op_real tm in
let lhs_th = low_approx lhs precision in
let rhs_th = hi_approx rhs precision in
let ll, lr = dest_binop le_op_real (concl lhs_th) in
let rl, rr = dest_binop le_op_real (concl rhs_th) in
let th0 = ASSUME tm in
let th1 = SPECL[ll; lr; rhs] REAL_LE_TRANS in
let th2 = SPECL[ll; rhs; rr] REAL_LE_TRANS in
let s1 = MATCH_MP th1 (CONJ lhs_th th0) in
MATCH_MP th2 (CONJ s1 rhs_th);;
let integer_approx_le_ineq precision ineq =
let lhs, rhs = dest_binop le_op_real ineq in
let m = (Int 10 **/ Int precision) in
let m_num, m_real = mk_numeral m, term_of_rat m in
let m_pos = SPEC m_num REAL_POS in
let mul_th = SPECL[m_real; lhs; rhs] REAL_LE_LMUL in
let th0 = MATCH_MP mul_th (CONJ m_pos (ASSUME ineq)) in
let th1 = (CONV_RULE ineq_rewrite_conv) th0 in
let approx = approx_le_ineq 0 (concl th1) in
PROVE_HYP th1 approx;;
let create_approximations precision_list ineq =
let ineq_th = ineq_rewrite_conv ineq in
let rhs = rand(concl ineq_th) in
let th0 = CONV_RULE (LAND_CONV (REWRITE_CONV[DECIMAL] THENC REAL_POLY_CONV))
(approx_le_ineq 8 rhs) in
let int_approx p =
let th1 = integer_approx_le_ineq p (concl th0) in
let th2 = PROVE_HYP th0 th1 in
let th3 = DISCH rhs th2 in
REWRITE_RULE[GSYM ineq_th] th3 in
map int_approx precision_list;;
(**********************************)
(*
let tm = `(&34/ &13 + pi/sol0)* x + &2 + -- &14 / &3 * z <= pi + rho218 + z * sol0 - u / &1000`;;
create_approximations [3;4;5] tm;;
*)
(*************************)
(* Additional step for generalizing hypotheses *)
let generalize_hyp th =
let gen_hyp = fun tm ->
let fn, arg = dest_comb (rand tm) in
if (is_comb fn && is_const (rator fn) && (fst o dest_const o rator) fn = "list_sum") then
let f, n = arg, rand fn in
UNDISCH_ALL (ISPECL[f; n] le_list_sum_hyp_gen)
else
UNDISCH_ALL (ISPECL[fn; arg] le_hyp_gen) in
let hyp_ths = map gen_hyp (hyp th) in
itlist PROVE_HYP hyp_ths th;;
(*
let tm = `list_sum n (\x. s x * r) + &1 / &3 * (azim_dart (V,E) o g) x <= pi`;;
let ths = create_approximations [3] tm;;
map generalize_hyp ths;;
*)
(*******************************)
let generate_ineqs precision_list ineq =
let create_approxs original_th precision_list =
let var, ineq = (dest_abs o rand o rator o concl) original_th in
let final_step = fun approx_th ->
let p_tm', q_tm' = dest_imp (concl approx_th) in
let p_tm, q_tm = mk_abs(var, p_tm'), mk_abs(var, q_tm') in
let list_tm = (rand o concl) original_th in
let mono_th = BETA_RULE (ISPECL[p_tm; q_tm; list_tm] (GEN_ALL MONO_ALL)) in
let s1 = MATCH_MP mono_th (GEN var approx_th) in
MATCH_MP s1 original_th in
let approx_ths0 = map generalize_hyp (create_approximations precision_list ineq) in
let approx_ths1 = map (itlist PROVE_HYP list_var_pos) approx_ths0 in
let approx_ths = map (REWRITE_RULE[GSYM LIST_SUM_LMUL]) approx_ths1 in
map final_step approx_ths in
let ineq_th = gen_general_ineq ineq in
let ineq = (snd o dest_abs o rand o rator o concl) ineq_th in
if (is_eq ineq) then
let eq_th = REWRITE_RULE[GSYM REAL_LE_ANTISYM; GSYM AND_ALL] ineq_th in
let ths1 = create_approxs (CONJUNCT1 eq_th) precision_list in
let ths2 = create_approxs (CONJUNCT2 eq_th) precision_list in
ths1, ths2
else
create_approxs ineq_th precision_list, [];;
(*********************************************************************)
(* Table containing all inequalities *)
let ineq_table = Array.init 6 (fun i -> Hashtbl.create 10);;
let ineq_test_table = Array.init 6 (fun i -> Hashtbl.create 10);;
let add_everything_to_table table =
let add_approximations_to_table = fun name ineq ->
let approxs', neg_approxs' = generate_ineqs [3;4;5] ineq in
let approxs = zip (3--5) approxs' in
let neg_approxs = if (neg_approxs' = []) then [] else zip (3--5) neg_approxs' in
let r = CONV_RULE (REWRITE_CONV[DECIMAL_INT] THENC DEPTH_CONV Arith_hash.NUMERAL_TO_NUM_CONV) in
let _ = map (fun (i, t) -> Hashtbl.add (ineq_test_table.(i)) name t;
Hashtbl.add (ineq_table.(i)) name (r t)) approxs in
let _ = map (fun (i, t) -> Hashtbl.add (ineq_test_table.(i)) (name^"_neg") t;
Hashtbl.add (ineq_table.(i)) (name^"_neg") (r t)) neg_approxs in
() in
Hashtbl.iter (fun name ineq -> add_approximations_to_table name ineq) table;;
let find_ineq precision name = Hashtbl.find ineq_table.(precision) name;;
let find_test_ineq precision name = Hashtbl.find ineq_test_table.(precision) name;;
(* Generate and add inequalities for constraints *)
add_everything_to_table constraints;;
add_everything_to_table var_bound_ineqs;;
(**************************)
(*
generate_ineqs [4] (get_ineq "ineq112");;
Hashtbl.iter (fun name ineq -> let _ = generate_ineqs[3;4;5] ineq in ()) constraints;;
*)
(***************)
(*********************)