Update from HH
[Flyspeck/.git] / text_formalization / hypermap / bauer_nipkow.hl
1 (* ========================================================================== *)
2 (* FLYSPECK - BOOK FORMALIZATION                                              *)
3 (*                                                                            *)
4 (* Chapter: hypermap                                                             *)
5 (* Author:  Thomas Hales     *)
6 (* Date: 2011-04-29                                                    *)
7 (* ========================================================================== *)
8
9 (* Port The Bauer-Nipkow completeness theorem from Isabelle,
10     based on
11    http://afp.sourceforge.net/browser_info/current/HOL/Flyspeck-Tame/outline.pdf
12
13    This is a human-translation of the Isabelle code.  As a correctness
14    check, it should be autmatically translated back into Isabelle,
15    then checked that the Isabelle thm implies the retranslation of the
16    thm here.
17
18    The tame_graph_classification_theorem is the translation into HOL
19    Light of the main result of Flyspeck I, Bauer-Nipkow.  To use it,
20    we should prove that a (restricted) planar hypermap has a
21    face listing that in bn_planar, and a tame hypermap has a
22    face listing that is bn_tame.
23
24 *)
25
26 needs "Library/rstc.ml";; (* for RTC reflexive transitive closure *)
27
28 (* flyspeck_needs "../../tame_archive/tame_archive.hl";; *)
29
30 module Tame_classification = struct
31
32   open Hales_tactic;;
33 (*
34 types: num, (A) list, (A ==> B), (A) Option, A#B, bool.
35 *)
36
37 let translate a = ();;
38
39 translate ("#",`CONS`);;
40 translate ("@",`APPEND`);;
41 translate ("!",`EL`);;
42 translate ("length",`LENGTH`);;
43 translate ("rev",`REVERSE`);;
44 translate ("?",`ITER`);;
45
46 (* List operations in Isabelle-Main:
47    op @, concat, filter, length, map, op !, remove1, rev, 
48    rotate, rotate1, upto, upt, zip.
49
50    Other things in main:
51    the,
52    See http://www.cl.cam.ac.uk/research/hvg/Isabelle/dist/Isabelle2013/doc/main.pdf
53 *)
54
55 (*
56 (* HOL Light definition from hypermap. Use ITER instead. *)
57
58 parse_as_infix("POWER",(24,"right"));;
59
60 let POWER = new_recursive_definition num_RECURSION 
61   `(!(f:A->A). f POWER 0  = I) /\  
62    (!(f:A->A) (n:num). f POWER (SUC n) = (f POWER n) o f)`;;
63 *)
64
65
66 (* import of 1.1 HOL *)
67
68 translate ("the",`the`);;
69
70 let the = new_definition `the s = @(x:A). (s = SOME x)`;;
71
72 let the_some = prove_by_refinement(
73   `!(x:A). the (SOME x) = x`,
74   (* {{{ proof *)
75   [
76   REWRITE_TAC[the];
77   GEN_TAC;
78   SELECT_TAC;
79     INTRO_TAC option_RECURSION [`x`;`I:A->A`];
80     REWRITE_TAC[I_THM];
81     REPEAT WEAKER_STRIP_TAC;
82     BY(ASM_MESON_TAC[]);
83   BY(ASM_MESON_TAC[])
84   ]);;
85   (* }}} *)
86
87
88 (* definition enum :: "nat \<Rightarrow> nat set" where
89   [code del]: "enum n = {..<n}" *)
90
91 (* let bn_enum  = new_definition `bn_enum (n: num) = { m | m < n } `;; *)
92
93 translate ("filter",`filter`);;
94
95 (* 1.2 length xs, 1.2.2 filter P xs, 1.2.3 concat,  *)
96
97 (*
98 let filter_liz = prove_by_refinement(
99   `filter (f:A->bool) [] = [] /\
100     filter f (x:: xs) = if (f x) then (x :: (filter f xs)) else filter f xs`,
101   (* {{{ proof *)
102   [
103     BY(REWRITE_TAC[Seq.filter])
104   ]);;
105   (* }}} *)
106
107 (*
108 let bn_filter = new_recursive_definition list_RECURSION
109   `bn_filter (f:A->bool) [] = [] /\
110     bn_filter f ( x:: xs) = if (f x) then (x :: (bn_filter f xs)) else bn_filter f xs`;;
111
112 let bn_filter_FILTER = prove_by_refinement (`bn_filter = FILTER`,
113   [
114   ONCE_REWRITE_TAC[FUN_EQ_THM];
115   GEN_TAC;
116   ONCE_REWRITE_TAC[FUN_EQ_THM];
117   LIST_INDUCT_TAC THEN ASM_REWRITE_TAC[FILTER;bn_filter];
118   ]);;
119 *)
120
121
122 let filter_FILTER = prove_by_refinement(
123   `filter = FILTER`,
124   (* {{{ proof *)
125   [
126   ONCE_REWRITE_TAC[FUN_EQ_THM];
127   GEN_TAC;
128   ONCE_REWRITE_TAC[FUN_EQ_THM];
129   BY(LIST_INDUCT_TAC THEN ASM_REWRITE_TAC[Seq.filter;FILTER])
130   ]);;
131   (* }}} *)
132
133 translate ("concat",`concat`);;
134
135
136 let concat = new_recursive_definition list_RECURSION
137   `concat ([]:(A list)list) = [] /\
138     concat ( (x:A list) :: xs) = APPEND x (concat xs)`;;
139
140 (* notation: disjoint_sum { x in xs } f  = concat (MAP (\x. f) xs) *)
141
142 (* list_update *)
143
144 (* 1.2.3 listProd1, listProd *)
145
146 translate ("map",`MAP`);;
147 translate ("listProd1",`list_prod1`);;
148 translate ("listProd",`list_prod`);;
149 translate ("bn_minimal",`bn_minimal`);;
150
151 Seq.map_MAP;; (`map = MAP`);;
152
153 let list_prod1 = new_definition `list_prod1 (a:A) (b:B list) = 
154    MAP(\x. (a,x)) b`;;
155
156 let list_prod = new_definition `list_prod (a:A list) (b:B list) =
157    concat (MAP (\x. list_prod1 x b) a)`;;
158
159 (* 1.2.5 *)
160
161 let bn_minimal = new_recursive_definition list_RECURSION
162   `(bn_minimal (f:A->num)  [] = CHOICE (UNIV:A->bool)) /\ 
163     (bn_minimal (f:A->num) ( (x:A) :: xs) = if (xs= []) then (x:A) else
164         (let m = bn_minimal f xs in (if(f x <= f m) then x else m)))`;;
165
166 (* benign redefinition from Misc_defs_and_lemmas module *)
167
168 translate ("min_list",`min_list`);;
169
170 let min_num = new_definition `min_num X = (@m. (m:num) IN X /\ (!n. n IN X ==> m <= n))`;;
171
172 let min_list = new_definition `min_list (xs:num list) = min_num (set_of_list xs)`;;
173
174 let min_num_single = prove_by_refinement(
175   `!x. min_num {x} = x`,
176   (* {{{ proof *)
177   [
178   GEN_TAC;
179   TYPIFY `x IN {x} ==> min_num {x} IN {x}` (C SUBGOAL_THEN MP_TAC);
180     REWRITE_TAC[IN];
181     BY(MESON_TAC[Misc_defs_and_lemmas.min_least ]);
182   BY(REWRITE_TAC[IN_SING])
183   ]);;
184   (* }}} *)
185
186 let min_num_in = prove_by_refinement(
187   `!X. ~(X = {}) ==> min_num X IN X`,
188   (* {{{ proof *)
189   [
190   REWRITE_TAC[EXTENSION;NOT_IN_EMPTY;NOT_FORALL_THM];
191   REWRITE_TAC[IN];
192   BY(MESON_TAC[Misc_defs_and_lemmas.min_least ])
193   ]);;
194   (* }}} *)
195
196 let min_num_le = prove_by_refinement(
197   `!X c. c IN X ==> min_num X <= c`,
198   (* {{{ proof *)
199   [
200   REWRITE_TAC[IN];
201   BY(MESON_TAC[Misc_defs_and_lemmas.min_least ])
202   ]);;
203   (* }}} *)
204
205 let min_num_unique = prove_by_refinement(
206   `!X c. c IN X /\ (!c'. c' IN X ==> c <= c') ==> min_num X = c`,
207   (* {{{ proof *)
208   [
209   REPEAT WEAKER_STRIP_TAC;
210   MATCH_MP_TAC (arith `x <= (c:num) /\ c <= x ==> x = c`);
211   CONJ_TAC;
212     MATCH_MP_TAC min_num_le;
213     BY(ASM_REWRITE_TAC[]);
214   FIRST_X_ASSUM MATCH_MP_TAC;
215   MATCH_MP_TAC min_num_in;
216   BY(FIRST_X_ASSUM MP_TAC THEN SET_TAC[])
217   ]);;
218   (* }}} *)
219
220 let min_num_insert = prove_by_refinement(
221   `!x X. ~(X = {}) ==> min_num (x INSERT X) = MIN x (min_num X)`,
222   (* {{{ proof *)
223   [
224   REPEAT GEN_TAC;
225   TYPIFY `x IN x INSERT X` (C SUBGOAL_THEN ASSUME_TAC);
226     BY(SET_TAC[]);
227   DISCH_TAC;
228   MATCH_MP_TAC min_num_unique;
229   CONJ_TAC;
230     REWRITE_TAC[MIN];
231     COND_CASES_TAC;
232       BY(SET_TAC[]);
233     TYPIFY `min_num X IN X` ENOUGH_TO_SHOW_TAC;
234       BY(SET_TAC[]);
235     MATCH_MP_TAC min_num_in;
236     BY(ASM_REWRITE_TAC[]);
237   REWRITE_TAC[IN_INSERT];
238   REPEAT STRIP_TAC;
239     ASM_REWRITE_TAC[];
240     BY(REWRITE_TAC[MIN] THEN ARITH_TAC);
241   MATCH_MP_TAC (arith `m <= min_num X /\ min_num X <= c' ==> m <= c'`);
242   CONJ_TAC;
243     BY(REWRITE_TAC[MIN] THEN ARITH_TAC);
244   MATCH_MP_TAC min_num_le;
245   BY(ASM_REWRITE_TAC[])
246   ]);;
247   (* }}} *)
248
249 let minn_MIN = prove_by_refinement(
250   `minn = MIN`,
251   (* {{{ proof *)
252   [
253   REWRITE_TAC[FUN_EQ_THM];
254   REWRITE_TAC[MIN;Ssrnat.minn];
255   BY(ARITH_TAC)
256   ]);;
257   (* }}} *)
258
259 let min_list_liz = prove_by_refinement(
260   `!x xs. min_list (x :: xs) = if (xs = []) then x else MIN x (min_list xs)`,
261   (* {{{ proof *)
262   [
263   REWRITE_TAC[min_list;set_of_list];
264   REPEAT GEN_TAC;
265   COND_CASES_TAC;
266     BY(ASM_REWRITE_TAC[set_of_list;min_num_single]);
267   MATCH_MP_TAC min_num_insert;
268   BY(ASM_REWRITE_TAC[SET_OF_LIST_EQ_EMPTY])
269   ]);;
270   (* }}} *)
271
272 (*
273 let max_num = new_definition `max_num (x:num->bool) = (@m. x m /\ (!n. x n ==> n <= m))`;;
274
275 let bn_max_list = new_definition `bn_max_list (xs:num list) = max_num (set_of_list xs)`;;
276 *)
277
278 (* 1.2.6 replace *)
279
280 translate ("replace",`replace`);;
281
282 let replace = new_recursive_definition list_RECURSION 
283    `(replace x ys [] = []) /\
284      replace x ys ( (z:A) :: zs) = 
285             if (z = x) then APPEND ys zs else z:: (replace x ys zs)`;;
286
287 (*
288 let sub_list = new_recursive_definition list_RECURSION
289    `sub_list r n xs [] = REVERSE xs /\
290      sub_list r n xs ( (y:A) :: ys) = if (n=0) then (APPEND (REVERSE xs) ( r :: ys)) 
291          else (sub_list r (n-1) ( y :: xs) ys)`;;
292 *)
293
294 translate ("mapAt",`bn_mapAt`);;
295
296 (* clean this up later.  Isabelle has special notation for (mapAt1 f n [] xs) *)
297
298 let mapAt1 = new_recursive_definition list_RECURSION
299    `mapAt1 (f:A->A) n xs [] = REVERSE xs /\
300      mapAt1 (f:A->A) n xs ((y:A) :: ys) = if (n=0) then (APPEND (REVERSE xs) ( (f y) :: ys)) 
301          else (mapAt1 f (n-1) (y :: xs) ys)`;;
302
303 let bn_mapAt = new_recursive_definition list_RECURSION 
304   `(bn_mapAt [] (f:A->A) (xs:A list) = xs) /\
305     (bn_mapAt ((n:num) :: ns) (f:A->A) (xs:A list) = if (n < LENGTH xs) 
306        then bn_mapAt ns f (mapAt1 f n [] xs) else bn_mapAt ns f xs)`;;
307
308 (* 1.2.9 rotate *)
309
310 translate ("rotate1",`rotate1`);;
311 translate ("rotate",`rotate`);;
312
313 (* `rot` is different because rot changes only up to the length of the list *)
314
315 let rotate1 = new_recursive_definition list_RECURSION
316    `rotate1 ([]:A list) = [] /\
317      rotate1 ((x:A) :: xs) = APPEND xs [x]`;;
318
319 let rotate = new_definition `rotate (n:num) (xs:A list) = (ITER n rotate1) xs`;;
320
321 (* 1.3 splitAt *)
322
323 translate ("splitAtRec",`splitAtRec`);;
324 translate ("splitAt",`splitAt`);;
325
326 let splitAtRec = new_recursive_definition list_RECURSION 
327  `splitAtRec (c:A) bs [] = (bs,[]) /\
328    splitAtRec c bs ((a:A) :: xs) = if (a = c) then (bs,xs) else splitAtRec c (APPEND bs [a]) xs`;;
329
330 let splitAt = new_definition `splitAt (c:A) xs = splitAtRec c [] xs`;;
331
332 (* 1.4 between *)
333
334 translate ("set",`set_of_list`);;
335 translate ("?",`IN`);;
336 translate ("between",`between'`);;  (* between is already used in HOL-Light *)
337
338 let between' = new_definition `between' (vs:A list) (ram1:A) (ram2:A) = 
339     (let (pre1,post1) = splitAt ram1 vs in
340        if (ram2 IN set_of_list post1) then
341          (let (pre2,post2) = splitAt ram2 post1 in pre2)
342        else (let (pre2,post2) = splitAt ram2 pre1 in APPEND post1 pre2))`;;
343
344 (* 1.5 Tables *)
345
346 (* type (a,b) table is (a#b) list *)
347
348 let bn_isTable = new_definition `bn_isTable (f:A->B) vs t =
349     !p. (set_of_list t p ==> ((SND p = f (FST p)) /\ set_of_list vs (FST p)))`;;
350
351 let bn_removeKey = new_definition `bn_removeKey a (ps:(A#B) list) = 
352     FILTER (\p. ~(a = FST p)) ps`;;
353
354 let bn_removeKeyList = new_recursive_definition list_RECURSION
355   `bn_removeKeyList [] ps = ps /\
356     bn_removeKeyList (w :: ws) (ps:(A#B) list) = bn_removeKey w (bn_removeKeyList ws ps)`;;
357
358 (*  infixes: =~ (congs) is congruence modulo rotation on lists,  -~ unused on lists.
359                   =~ is pr_isomorphism on graphs, -~ isomorphic of graphs.
360
361      {=~} is Isabelle notation for {(f1,f2). f1 =~ f2}.
362
363     type a Fgraph  a list -> bool
364             a fgraph a list list
365 *)
366
367 let bn_congs = new_definition `bn_congs (f1:A list) f2 = ?n. f2 = rotate n f1`;;
368
369 (* 2.2 homomorphism and isomorphism *)
370
371 let bn_is_Hom = new_definition`bn_is_Hom (phi:A->B) Fs1 Fs2 = 
372   IMAGE bn_congs (IMAGE (MAP phi) Fs1)
373   = IMAGE bn_congs (Fs2)`;;
374
375 let bn_inj_on = new_definition 
376   `bn_inj_on (f:A->B) s = ( !x y. (s x /\ s y /\ (f x = f y)) ==> (x = y))`;;
377
378 let bn_is_pr_Iso = new_definition `bn_is_pr_Iso (phi:A->B) Fs1 Fs2 = 
379    (bn_is_Hom phi Fs1 Fs2 /\ bn_inj_on phi (UNIONS (IMAGE set_of_list Fs1)))`;;
380
381 let bn_is_hom = new_definition
382    `bn_is_hom (phi:A->B) fs1 fs2 = bn_is_Hom phi (set_of_list fs1) (set_of_list fs2)`;;
383
384 let bn_is_pr_iso = new_definition
385  `bn_is_pr_iso (phi:A->B) fs1 fs2  = bn_is_pr_Iso phi (set_of_list fs1) (set_of_list fs2)`;;
386
387 (* 
388 I don't think I'll need these:
389 *)
390
391 (* bn_pr_iso_test0, bn_pr_iso_test1,  *)
392
393 (* 2.3.1 
394    def bn_oneone, 
395     types (A,B) tester, (A,B) merger.
396    def bn_pr_iso_test2
397    def bn_test:(A,B) tester
398    bn_merge:(A,B) merger
399    bn_test2:(A,B) tester
400    bn_merge2:(A,B) merger
401    bn_pr_iso_test3,
402    bn_pr_iso_test,
403 *)
404
405 (* 2.3.2, improper isomorphisms *)
406
407 let bn_is_Iso = new_definition `bn_is_Iso (phi:A->B) Fs1 Fs2 = 
408    (bn_is_pr_Iso phi Fs1 Fs2 \/ bn_is_pr_Iso phi Fs1 (IMAGE REVERSE Fs2))`;;
409
410 let bn_is_iso = new_definition `bn_is_iso (phi:A->B) fs1 fs2 = 
411    bn_is_Iso phi (set_of_list fs1) (set_of_list fs2)`;;
412
413 let bn_cong_iso = new_definition 
414   `bn_cong_iso fs1 fs2 = ?(phi:A->B). bn_is_iso phi fs1 fs2`;;
415
416 let bn_cong_pr_iso = new_definition 
417   `bn_cong_pr_iso fs1 fs2 = ?(phi:A->B). bn_is_pr_iso phi fs1 fs2`;;
418
419 (* -~ abbrev for bn_cong_iso, =~ bn_cong_pr_iso *)
420
421 (* bn_iso_test,
422 *)
423
424 (* 2.4 Elementhood *)
425
426 (* XX drop primes *)
427
428 let bn_pr_iso_in = new_definition
429   `bn_pr_iso_in (x:(A list) list) M = ?(y:(B list) list). (bn_cong_pr_iso x y /\ M y)`;;
430
431 let bn_pr_iso_subseteq = new_definition
432   `bn_pr_iso_subseteq (M:(A list) list -> bool) (N:(B list) list -> bool) 
433      = !x. M x ==> bn_pr_iso_in x N`;;
434
435 let bn_iso_in = new_definition
436   `bn_iso_in (x:(A list) list) M = ?(y:(B list) list). (bn_cong_iso x y /\ M y)`;;
437
438 let bn_iso_subseteq = new_definition
439   `bn_iso_subseteq (M:(A list) list -> bool) (N:(B list) list -> bool) 
440      = !x. M x ==> bn_iso_in x N`;;
441
442 (* 3.0 More rotation *)
443
444 let rotate_to = new_definition `rotate_to (vs:A list) v = 
445     v :: (APPEND (SND (splitAt v vs))  (FST (splitAt v vs)))`;;
446
447 let rotate_min = new_definition `rotate_min (vs:num list) = 
448   rotate_to vs (min_list vs)`;;  
449
450 (* 4.0 Graph
451
452 UNION1
453 INTER1
454 UNION
455 INTER
456
457 types vertex = nat
458
459 const
460   vertices
461   edges
462
463 abbrev vertices_set
464
465 4.2 Faces
466
467    facetype = Final | Nonfinal
468    datatype face = Face (vertex list) facetype
469    consts final:A->bool
470         type:A->facetype
471    
472     final_face = final:face->bool
473     type_face = type:face->facetype
474     vertices_face = vertices:face -> vertex list
475
476
477 *)
478
479 let bn_final_face = new_definition `bn_final_face (vs:A,f:bool) = f`;;
480
481 (* bn_type_face  = bn_final_face *)
482
483 let bn_vertices_face = new_definition `bn_vertices_face (vs:A,f:B) = vs`;;
484
485 let bn_vertices_set = new_definition `bn_vertices_set (fs:A list#B) = 
486   set_of_list (bn_vertices_face fs)`;;
487
488 (* =~ on faces means =~ on vertex list *)
489
490 (* delete:
491 let bn_set_final = new_definition `bn_set_final (vs:A,f:bool) = (vs,T)`;;
492 *)
493
494 let bn_setFinal = new_definition `bn_setFinal (vs:A,f:bool) = (vs,T)`;;
495
496 (* nextVertex written as a dot . *)
497
498 let bn_nextElem = new_recursive_definition list_RECURSION 
499   `bn_nextElem [] (b:A) x = b /\
500     bn_nextElem (a :: aas) b x = 
501      if (x=a) then (if (LENGTH aas = 0) then b else HD aas) else bn_nextElem aas b x`;;
502
503 let bn_nextVertex = new_definition `bn_nextVertex (vs:A list,f:bool) =
504    bn_nextElem vs (HD vs)`;;
505
506 let bn_edges = new_definition `bn_edges (fs:A list # bool)  =
507    IMAGE (\a. (a, bn_nextVertex fs a)) (bn_vertices_set fs)`;;
508
509 let bn_nextVertices = new_definition `bn_nextVertices (vs:A list,f:bool) (n:num) v = 
510     (ITER n (bn_nextVertex (vs,f))) v`;;
511
512 (* op = REVERSE,  op_graph = Graph.op, op_graph *)
513
514 let bn_prevVertex = new_definition `bn_prevVertex (vs:A list,f:bool) v =
515    (bn_nextElem (REVERSE vs) (LAST vs) v)`;;
516
517 let bn_triangle = new_definition `bn_triangle (vs:A list,f:bool) = (LENGTH vs = 3)`;;
518
519 (* 4.3 Graphs *)
520
521 (* XX drop primes *)
522
523 (*
524 bn_graph:
525 list of faces (with boolean marking if each face is final),
526 number of vertices,
527 list whose ith entry is the list of faces containing vertex i,
528 a list of heights.
529 *)
530
531 let new_graph_th = prove(`?(x:((num list # bool) list) #  (num) 
532    # (((num list # bool) list) list) # (num list))  . T`,MESON_TAC[]);;
533
534 let bn_graph_type = new_type_definition 
535   "bn_graph" ("mk_bn_graph","dest_bn_graph") new_graph_th;;
536
537 let bn_faces = new_definition `bn_faces g = FST (dest_bn_graph g)`;;
538
539 (* abbrev F *)
540
541 let bn_Faces = new_definition `bn_Faces g = set_of_list (bn_faces g)`;;
542
543 let bn_countVertices = new_definition
544   `bn_countVertices g = FST (SND (dest_bn_graph g))`;;
545
546 let bn_vertices_graph = new_definition 
547  `bn_vertices_graph g = 0.. (bn_countVertices g - 1)`;;
548
549 let bn_faceListAt = new_definition
550   `bn_faceListAt g = FST (SND (SND (dest_bn_graph g)))`;;
551
552 let bn_facesAt = new_definition
553   `bn_facesAt g v = EL v (bn_faceListAt g )`;;
554
555 let bn_heights = new_definition `bn_heights g = SND(SND(SND(dest_bn_graph g)))`;;
556
557 let bn_height = new_definition `bn_height g v = EL v (bn_heights g)`;;
558
559 (* seed *)
560
561 let LIST_TO = new_recursive_definition num_RECURSION
562   `LIST_TO 0 = [] /\ LIST_TO (SUC n) = APPEND (LIST_TO n) [n]`;;
563
564 let UPT= new_recursive_definition num_RECURSION
565    `UPT m 0 = [] /\ (UPT m (SUC n) = if (n < m) then [] else APPEND (UPT m n) [n]  )`;;
566
567 (* notation: [m..<n] = UPT m n *)
568
569 (* could replace LIST_TO with UPT 0 *)
570
571 let bn_graph = new_definition  `bn_graph n = 
572      (let vs = LIST_TO n in
573       let fs =  [(vs,T);(vs,F)] in
574         mk_bn_graph (    fs , n, REPLICATE n fs, REPLICATE n 0))`;;
575
576 (* 4.4 Operations on graphs *)
577
578 let bn_finals = new_definition `bn_finals g =
579    FILTER bn_final_face (bn_faces g)`;;
580
581 let bn_nonFinals = new_definition `bn_nonFinals g = 
582    FILTER (\r. ~( bn_final_face r)) (bn_faces g)`;;
583
584 let bn_countNonFinals = new_definition `bn_countNonFinals g =
585    LENGTH (bn_nonFinals g)`;;
586
587 let bn_finalGraph = new_definition `bn_finalGraph g = (bn_countNonFinals g = 0)`;;
588
589 let bn_finalVertex = new_definition `bn_finalVertex g v = 
590    (!f.  set_of_list(bn_facesAt g v) f ==> bn_final_face f)`;;
591
592 let bn_degree = new_definition `bn_degree g v = LENGTH(bn_facesAt g v)`;;
593
594 let bn_tri = new_definition  `bn_tri g v =
595     LENGTH(FILTER (\f. bn_final_face f /\ LENGTH(bn_vertices_face f)=3) (bn_facesAt g v))`;;
596
597 let bn_quad = new_definition  `bn_quad g v =
598     LENGTH(FILTER (\f. bn_final_face f /\ LENGTH(bn_vertices_face f)=4) (bn_facesAt g v))`;;
599
600 let bn_except = new_definition  `bn_except g v =
601     LENGTH(FILTER (\f. bn_final_face f /\ 5 <= LENGTH(bn_vertices_face f)) (bn_facesAt g v))`;;
602
603 let bn_vertextype = new_definition `bn_vertextype g v = 
604     (bn_tri g v, bn_quad g v, bn_except g v)`;;
605
606 let bn_exceptionalVertex = new_definition `bn_exceptionalVertex g v = 
607   ~(bn_except g v = 0)`;;
608
609 let bn_noExceptionals = new_definition   `bn_noExceptionals g V =
610    (!v. V v ==> ~(bn_exceptionalVertex g v))`;;
611
612 let bn_edges_graph = new_definition
613   `bn_edges_graph g = UNIONS { bn_edges f | bn_Faces g f }`;; 
614
615 let bn_neighbors = new_definition
616   `bn_neighbors g v = MAP (\f. bn_nextVertex f v )  (bn_facesAt g v)`;;
617
618 (* 4.5 Navigation in graphs *)
619
620 (* nextFace *)
621
622 let bn_directedLength = new_definition `bn_directedLength f (a:A) b =
623   if (a=b) then 0 else LENGTH(between'(bn_vertices_face f) a b) + 1`;;
624
625 (* 4.6 Code generator setup *)
626
627 (* 5 Vector *)
628
629 (* vector = list *)
630
631 (* 5.1 Tabulation *)
632
633 let bn_tabulate0 = new_definition `bn_tabulate0 (p:num# (num->A)) =
634     (MAP (SND p) (LIST_TO (FST p)))`;;
635
636 let bn_tabulate = new_definition `bn_tabulate n (f:num->A) = bn_tabulate0 (n,f)`;;
637
638 let bn_tabulate2 = new_definition `bn_tabulate2 m n (f:num->num->A) =
639    bn_tabulate m (\i. bn_tabulate n (f i))`;;
640
641 let bn_tabulate3 = new_definition `bn_tabulate3 l m n (f:num->num->num->A) =
642    bn_tabulate l (\i. bn_tabulate m (\j. bn_tabulate n (\k. f i j k)))`;;
643
644 (*
645 syntax. [f. x < n], [f. x < m, y < n], [f. x < l, y < m, z < n].
646 *)
647
648 (* 5.2 Access *)
649
650 let bn_sub1 = new_definition `bn_sub1 ((xs:A list), (n:num)) = EL n xs`;;
651    
652 let bn_sub = new_definition `bn_sub   (a:A list) n = bn_sub1 (a,n)`;;
653
654 (* notaton: a[n] = sub a n, a[m,n] = sub (sub a m) n, a[l,m,n] = sub(sub(sub a l)m)n *)
655
656
657 (* 6 Enumerating Patches  *)
658
659 let bn_enumBase = new_definition 
660   `bn_enumBase nmax = MAP (\i. [i]) (LIST_TO (SUC nmax))`;;
661
662 let bn_enumAppend = new_definition
663    `bn_enumAppend nmax iss = 
664    concat (MAP (\is.   MAP (\n. APPEND is [n]) (UPT (LAST is) (SUC nmax))) iss)`;;
665
666 let bn_enumerator = new_definition
667    `bn_enumerator inner outer = 
668       (let nmax = outer - 2 in
669        let k = inner - 3 in
670        (MAP (\is. APPEND [0] (APPEND is [outer -1])) 
671           ((bn_enumAppend nmax POWER k) (bn_enumBase nmax))))`;;
672
673 let bn_enumTab = new_definition
674   `bn_enumTab = bn_tabulate2 9 9 bn_enumerator`;;
675
676 (* bn_enum already defined above, call this bn_enumt *)
677
678 let bn_enumt = new_definition `bn_enumt inner outer = 
679    if (inner < 9 /\ outer < 9) then (bn_sub(bn_sub bn_enumTab inner) outer) else
680     bn_enumerator inner outer`;;
681
682 let bn_hideDupsRec = new_recursive_definition list_RECURSION 
683   `bn_hideDupsRec (a:A) [] = []  /\
684     bn_hideDupsRec a (b :: bs) = 
685       if (a = b) then NONE :: (bn_hideDupsRec b bs) 
686       else  (SOME b) :: (bn_hideDupsRec b bs)`;;
687
688 let bn_hideDups = new_recursive_definition list_RECURSION
689   `bn_hideDups ([]:A list) = [] /\
690     bn_hideDups ((b:A) :: bs) = (SOME b) :: (bn_hideDupsRec b bs)`;;
691
692 let bn_indexToVertexList = new_definition `bn_indexToVertexList f v is = 
693   bn_hideDups (MAP (\k. bn_nextVertices f k (v:A)) is)`;;
694
695 (* 7 Subdividing a Face *)
696
697 let bn_split_face = new_definition 
698    `bn_split_face f (ram1:A) ram2 newVs = 
699       (let vs = bn_vertices_face f in
700        let f1 = APPEND [ram1] (APPEND (between' vs ram1 ram2) [ram2]) in
701        let f2 = APPEND [ram2] (APPEND (between' vs ram2 ram1) [ram1]) in
702          ((APPEND (REVERSE newVs) f1,F), ((APPEND f2 newVs), F)))`;;
703
704 let bn_replacefacesAt = new_definition
705   `bn_replacefacesAt ns f fs Fs = bn_mapAt ns (replace f fs) Fs`;;
706
707 let bn_makeFaceFinalFaceList = new_definition
708   `bn_makeFaceFinalFaceList f fs = replace f [bn_setFinal f] fs`;;
709
710 let bn_makeFaceFinal = new_definition
711   `bn_makeFaceFinal f g = 
712       mk_bn_graph (
713         bn_makeFaceFinalFaceList f (bn_faces g),
714         bn_countVertices g,
715         MAP (\fs. bn_makeFaceFinalFaceList f fs) (bn_faceListAt g),
716         (bn_heights g)
717       )`;;
718
719 let bn_heightsNewVertices = new_definition 
720   `bn_heightsNewVertices h1 h2 n = 
721        MAP (\i. min_num { (h1 + i + 1), (h2 + n -i) } ) (LIST_TO n)`;;
722
723 let bn_splitFace = new_definition
724   `bn_splitFace g ram1 ram2 oldF newVs = 
725      (let fs = bn_faces g in
726       let n = bn_countVertices g in
727       let Fs = bn_faceListAt g in
728       let h = bn_heights g in
729       let lVs = LENGTH(newVs) in
730       let vs1 = between' (bn_vertices_face oldF) ram1 ram2 in
731       let vs2  = between' (bn_vertices_face oldF) ram2 ram1 in
732       let (f1,f2) = bn_split_face oldF ram1 ram2 newVs in
733       let Fs = bn_replacefacesAt vs1 oldF [f1] Fs in
734       let Fs = bn_replacefacesAt vs2 oldF [f2] Fs in
735       let Fs = bn_replacefacesAt [ram1] oldF [f2;f1] Fs in
736       let Fs = bn_replacefacesAt [ram2] oldF [f1;f2] Fs in
737       let Fs = APPEND Fs (REPLICATE lVs [f1;f2]) in
738           (f1,f2, mk_bn_graph ((APPEND(replace oldF [f2] fs ) [f1]), (n + lVs),
739                                  Fs,(APPEND h (bn_heightsNewVertices (EL ram1 h) (EL ram2 h) lVs)))
740         ))`;;
741
742 (* XX replaced @ with 'the' vo *)
743
744 let bn_subdivFace0 = new_recursive_definition list_RECURSION
745   `bn_subdivFace0 g f u n [] = bn_makeFaceFinal f g /\
746     bn_subdivFace0 g f u n (vo :: vos) = 
747       if (vo = NONE) then bn_subdivFace0 g f u (SUC n) vos else
748         (let v = the vo in
749            if (bn_nextVertex f u = v /\ n = 0) then bn_subdivFace0 g f v 0 vos
750            else 
751              (let ws = UPT (bn_countVertices g) (bn_countVertices g + n) in
752               let (f1,f2,g') = bn_splitFace g u v f ws in
753                 bn_subdivFace0 g' f2 v 0 vos))`;;
754
755 let bn_subdivFace = new_definition 
756   `bn_subdivFace g f vos = bn_subdivFace0 g f (the(HD vos)) 0 (TL vos)`;;
757
758
759 (* 8. Transitive closure *)
760
761 (* doing it somewhat differently from the Isabelle since Library/rstc.ml
762     already does the reflexive and transitive closure of a relation *)
763
764 let bn_RTranCl = new_definition `bn_RTranCl (g:A -> A list) = 
765   UNCURRY    (RTC (\x y.  MEM y (g x)))`;;
766
767 let bn_invariant = new_definition `bn_invariant (P:A->bool) succs = 
768    !g g'. MEM g (succs g) ==> P g ==> P g'`;;
769
770 (* notation: g  [s]->*   g'   for (g,g') IN (RTranCl s)  *)
771
772 (* 9. Plane Graph Enumeration  *)
773
774 let bn_maxGon = new_definition `bn_maxGon (p:num) = p + 3`;;
775
776 let bn_duplicateEdge = new_definition `bn_duplicateEdge g f a b =
777    (2 <= bn_directedLength f a b /\ 2 <= bn_directedLength f b a /\
778     set_of_list (bn_neighbors g a) b)`;;
779
780 let bn_containsUnacceptableEdgeSnd = new_recursive_definition list_RECURSION
781   `bn_containsUnacceptableEdgeSnd N (v:num) [] = F /\
782     bn_containsUnacceptableEdgeSnd N v (w :: ws) = 
783   if (LENGTH ws = 0) then F else
784     (let w' = HD ws in
785      let ws' = TL ws in
786   if (v < w /\ w < w' /\ N w w') then T 
787   else bn_containsUnacceptableEdgeSnd N w ws)`;;
788   
789 let bn_containsUnacceptableEdge = new_recursive_definition list_RECURSION
790   `bn_containsUnacceptableEdge N [] = F /\
791   bn_containsUnacceptableEdge N (v :: vs) = 
792   if (LENGTH vs = 0) then F else
793     (let w = HD vs in
794      let ws = TL vs in
795        if ((v:num) < w /\ N v w) then T else bn_containsUnacceptableEdgeSnd N v vs)`;;
796
797 let bn_containsDuplicateEdge = new_definition
798   `bn_containsDuplicateEdge g f v is = bn_containsUnacceptableEdge
799     (\i j. bn_duplicateEdge g f (bn_nextVertices f i v ) (bn_nextVertices f j v)) is`;;
800
801 (* a lemma in 13.3 proves this to be the same *)
802
803 let bn_containsDuplicateEdge0 = new_definition
804   `bn_containsDuplicateEdge0 g f v is =
805   ((2 <= LENGTH is) /\ 
806     ((?k. (k < LENGTH is - 2) /\ 
807         (let i0 = EL k is in
808          let i1  = EL (k+1) is in
809          let i2 = EL (k+2) is in
810            (bn_duplicateEdge g f (bn_nextVertices f i1 v) (bn_nextVertices f i2 v) /\
811               (i0 < i1 /\ i1 < i2))))
812         \/
813         (let i0 = EL 0 is in
814          let i1 = EL 1 is in
815            (bn_duplicateEdge g f (bn_nextVertices f i0 v) (bn_nextVertices f i1 v) /\
816               (i0 < i1)))))`;;
817
818 let bn_generatePolygon = new_definition 
819   `bn_generatePolygon n v f g = 
820   (let enumeration = bn_enumerator n (LENGTH (bn_vertices_face f)) in
821    let enumeration = FILTER (\is. ~(bn_containsDuplicateEdge g f v is)) enumeration in
822    let vertexLists = MAP (\is. bn_indexToVertexList f v is) enumeration in
823      MAP (\vs. bn_subdivFace g f vs) vertexLists)`;;
824
825 (* concatenated union *)
826
827 let c_union = new_definition `c_union xs r = concat (MAP r xs)`;;
828
829 let bn_Seed = new_definition
830   `bn_Seed p = bn_graph (bn_maxGon p)`;;
831
832 (*
833
834 let bn_next_plane0 = new_definition
835   `bn_next_plane0 p g = if (bn_finalGraph g) then [] else
836     c_union (bn_nonFinals g) 
837       (\f. c_union (bn_vertices_face f)
838          (\v. c_union (UPT 3 (SUC(bn_maxGon p)))
839             (\i. bn_generatePolygon i v f g)))`;;
840
841
842 let bn_PlaneGraphs0 = new_definition
843  `bn_PlaneGraphs0 = 
844    { g | ? p.   bn_RTranCl (bn_next_plane0 p) (bn_Seed p,g) /\ bn_finalGraph g }`;;
845
846 *)
847
848 (* Plane1 *)
849
850 let bn_minimalFace = new_definition 
851  `bn_minimalFace = bn_minimal (LENGTH o bn_vertices_face)`;;
852
853 let bn_minimalVertex = new_definition
854   `bn_minimalVertex g f = bn_minimal (bn_height g) (bn_vertices_face f)`;;
855
856 let bn_next_plane = new_definition
857   `bn_next_plane p g = 
858   (let fs = bn_nonFinals g in
859      if (fs = []) then [] else
860        (let f = bn_minimalFace fs in
861         let v = bn_minimalVertex g f in
862           c_union (UPT 3 (SUC (bn_maxGon p))) (\i. bn_generatePolygon i v f g)))`;;
863
864 let bn_PlaneGraphsP = new_definition
865   `bn_planeGraphsP p = 
866    { g | bn_RTranCl (bn_next_plane p) (bn_Seed p,g) /\ bn_finalGraph g} `;;
867
868 let bn_PlaneGraphs = new_definition
869 `bn_PlaneGraphs = UNIONS (IMAGE bn_planeGraphsP (:num))`;;
870
871 (* 10 Properties *)
872
873 (* 11 Properties of Patch Enumeration *)
874
875 (* bn_increasing *)
876
877 (* 12 Properties of Face Division *)
878
879 (* bn_is_prefix *)
880
881 (* bn_is_sublist *)
882
883 (* 12.4,  bn_is_nextElem *)
884 (* 12.6,  bn_before *)
885 (* 12.7,  bn_pre_between *)
886 (* 12.8,  bn_pre_split_face *)
887 (* 12.9, bn_verticesFrom  *)
888 (* 12.10 bn_pre_splitFace, bn_Edges,  *)
889 (* 12.11 bn_removeNones *)
890 (* 12.12 bn_natToVertexListRec, bn_natToVertexList *)
891 (* 12.13 bn_is_duplicateEdge, bn_invalidVertexList *)
892 (* 12.14 bn_subdivFace, bn_pre_subdivFace, bn_pre_subdivFace0 *)
893
894 (* 13 *)
895
896 (* 13.1, bn_minVertex, bn_normFace, bn_normFaces, 
897 etc. etc.
898
899 *)
900
901
902 (* 16 Tameness *)
903
904 let bn_squanderTarget = new_definition `bn_squanderTarget = 15410`;;
905
906 let bn_excessTCount = new_definition `bn_excessTCount = 6300`;;
907
908 let bn_squanderVertex = new_definition `bn_squanderVertex p q = 
909   if (p=0 /\ q=3) then 6180 else
910     if (p=0 /\ q=4) then 9700 else
911       if (p=1 /\ q=2) then 6560 else
912         if (p=1 /\ q=3) then 6180 else
913           if (p=2 /\ q=1) then 7970 else
914             if (p=2 /\ q=2) then 4120 else
915               if (p=2 /\ q=3) then 12851 else
916                 if (p=3 /\ q=1) then 3110 else
917                   if (p=3 /\ q=2) then 8170 else
918                     if (p=4 /\ q=0) then 3470 else
919                       if (p=4 /\ q=1) then 3660 else
920                         if (p=5 /\ q=0) then 400 else
921                           if (p=5 /\ q=1) then 11360 else
922                             if (p=6 /\ q=0) then 6860 else
923                               if (p=7 /\ q=0) then 14500 else bn_squanderTarget`;;
924
925 let bn_squanderFace = new_definition `bn_squanderFace n = 
926   if (n=3) then 0 else
927     if (n=4) then 2060 else
928       if (n=5) then 4819 else
929         if (n=6) then 7120 else bn_squanderTarget`;;
930 (* tchales, changed n=6 case from 7578, 1/15/2012 to match
931     tame_defs.hl, main_estimate_ineq.hl and graph generator *)
932
933 (*
934 let bn_separated2 = new_definition `bn_separated2 g V = 
935   !v.  V v ==> ( !f. (MEM f (bn_facesAt g v)) ==> ~(V (bn_nextVertex f v)))`;;
936
937 let bn_separated3 = new_definition `bn_separated3 g V = 
938   !v. V v ==> (!f. (MEM f (bn_facesAt g v)) ==> LENGTH (bn_vertices_face f)<= 4 ==>
939                  (bn_vertices_set f INTER V = { v }) )`;;
940
941 let bn_separated = new_definition `bn_separated g V = 
942   (bn_separated2 g V /\ bn_separated3 g V)`;;
943 *)
944
945
946 (* 16.3 Admissible weight assignments *)
947
948 let bn_admissible1 = new_definition `bn_admissible1 w g =
949   (!f. bn_Faces g f ==> bn_squanderFace (LENGTH (bn_vertices_face f)) <= w f)`;;
950
951 let LIST_SUM = new_definition `LIST_SUM xs (f:A->num) = ITLIST (\x y. f x + y) xs 0`;;
952
953 let bn_admissible2 = new_definition  `bn_admissible2 w g = 
954   (!v. bn_vertices_graph g v ==> (bn_except g v = 0) ==> 
955      bn_squanderVertex (bn_tri g v) (bn_quad g v) <= LIST_SUM (bn_facesAt g v) w)`;;
956
957 let bn_admissible3 = new_definition `bn_admissible3 w g = 
958   (!v. bn_vertices_graph g v ==> (bn_vertextype g v = (5,0,1)) ==>
959      (LIST_SUM (FILTER bn_triangle (bn_facesAt g v)) w >= bn_excessTCount))`;;
960
961 let bn_admissible = new_definition `bn_admissible w g = 
962   (bn_admissible1 w g /\ bn_admissible2 w g /\ bn_admissible3 w g) `;;
963
964 (* 16.4 Tameness *)
965
966 let bn_tame9a = new_definition `bn_tame9a g = 
967   (!f. bn_Faces g f ==> 
968      3 <= LENGTH(bn_vertices_face f) /\ LENGTH(bn_vertices_face f) <= 6)`;;
969
970 let bn_tame10 = new_definition `bn_tame10 g = 
971   (let n = bn_countVertices g in
972      13 <= n /\ n <= 15)`;;
973
974 let bn_tame11a = new_definition `bn_tame11a g = 
975   (!v. bn_vertices_graph g v ==>  3 <= bn_degree g v)`;;
976
977 let bn_tame11b = new_definition `bn_tame11b g = 
978   (!v. bn_vertices_graph g v ==> 
979      bn_degree g v <= (if (bn_except g v = 0) then 7 else 6))`;;
980
981 let bn_tame12o = new_definition `bn_tame12o g = 
982   (!v. bn_vertices_graph g v ==>
983      (~(bn_except g v = 0) /\ bn_degree g v = 6) ==> (bn_vertextype g v = (5,0,1)))`;;
984
985 let bn_tame13a = new_definition `bn_tame13a g = 
986   (?w. bn_admissible w g /\ LIST_SUM (bn_faces g) w < bn_squanderTarget)`;;
987
988 let bn_tame = new_definition `bn_tame g= 
989   (bn_tame9a g /\ bn_tame10 g/\ bn_tame11a g/\ 
990     bn_tame11b g/\ bn_tame12o g/\ bn_tame13a g)`;;
991   
992 (* 26 *)
993
994 let bn_fgraph = new_definition `bn_fgraph g = MAP bn_vertices_face (bn_faces g)`;;
995
996 (* the list bn_Archive is the concatenation of bn_Tri, bn_Quad, bn_Pent, and bn_Hex.
997     These definitions need to be loaded from the Arch theory (which converts
998     them from .ML files)  *)
999
1000 (*  (* bn_tame_archive is defined in ../../tame_archive/tame_archive.hl *)
1001 let tame_graph_classification_theorem = (* new_definition *)
1002   `tame_graph_classification_theorem = 
1003   (!g. bn_PlaneGraphs g /\ bn_tame g ==> bn_iso_in (bn_fgraph g)   bn_tame_archive)`;;
1004
1005 *)
1006
1007
1008 *)
1009
1010
1011 end;;