-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lattice.thy
2258 lines (1795 loc) · 111 KB
/
Lattice.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
theory Lattice
imports Base
begin
section {* Lattices and Orders *}
subsection {* Partial orders *}
record 'a ord = "'a partial_object" +
le :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubseteq>\<index>" 50)
locale order = fixes A (structure)
assumes order_refl [intro, simp]: "x \<in> carrier A \<Longrightarrow> x \<sqsubseteq> x"
and order_trans: "\<lbrakk>x \<sqsubseteq> y; y \<sqsubseteq> z; x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"
and order_antisym: "\<lbrakk>x \<sqsubseteq> y; y \<sqsubseteq> x; x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x = y"
subsubsection {* Order duality *}
definition ord_inv :: "('a, 'b) ord_scheme \<Rightarrow> ('a, 'b) ord_scheme" ("_\<sharp>" [1000] 100) where
"ord_inv ordr \<equiv> \<lparr>carrier = carrier ordr, le = \<lambda>x y. le ordr y x, \<dots> = ord.more ordr\<rparr>"
lemma inv_carrier_id [simp]: "carrier (ord_inv A) = carrier A"
by (metis ord_inv_def partial_object.simps(1))
lemma ord_to_inv: "order A \<Longrightarrow> order (ord_inv A)"
by (default, simp_all add: ord_inv_def, (metis order.order_refl order.order_trans order.order_antisym)+)
lemma inv_inv_id: "ord_inv (A\<sharp>) = A"
by (simp add: ord_inv_def)
lemma inv_to_ord: "order (A\<sharp>) \<Longrightarrow> order A"
by (metis inv_inv_id ord_to_inv)
lemma ord_is_inv [simp]: "order (A\<sharp>) = order A"
by (metis inv_to_ord ord_to_inv)
lemma inv_flip [simp]: "(x \<sqsubseteq>\<^bsub>A\<sharp>\<^esub> y) = (y \<sqsubseteq>\<^bsub>A\<^esub> x)"
by (simp add: ord_inv_def)
lemma dual_carrier_subset: "X \<subseteq> carrier A \<longleftrightarrow> X \<subseteq> carrier (A\<sharp>)"
by (metis inv_carrier_id)
subsubsection {* Isotone functions *}
definition isotone :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"isotone A B f \<equiv> order A \<and> order B \<and> (\<forall>x\<in>carrier A. \<forall>y\<in>carrier A. x \<sqsubseteq>\<^bsub>A\<^esub> y \<longrightarrow> f x \<sqsubseteq>\<^bsub>B\<^esub> f y)"
lemma use_iso1: "\<lbrakk>isotone A A f; x \<in> carrier A; y \<in> carrier A; x \<sqsubseteq>\<^bsub>A\<^esub> y\<rbrakk> \<Longrightarrow> f x \<sqsubseteq>\<^bsub>A\<^esub> f y"
by (simp add: isotone_def)
lemma use_iso2: "\<lbrakk>isotone A B f; x \<in> carrier A; y \<in> carrier A; x \<sqsubseteq>\<^bsub>A\<^esub> y\<rbrakk> \<Longrightarrow> f x \<sqsubseteq>\<^bsub>B\<^esub> f y"
by (simp add: isotone_def)
lemma iso_compose: "\<lbrakk>f \<in> carrier A \<rightarrow> carrier B; isotone A B f; g \<in> carrier B \<rightarrow> carrier C; isotone B C g\<rbrakk> \<Longrightarrow> isotone A C (g \<circ> f)"
by (simp add: isotone_def, safe, metis (full_types) typed_application)
lemma inv_isotone [simp]: "isotone (A\<sharp>) (B\<sharp>) f = isotone A B f"
by (simp add: isotone_def, auto)
definition idempotent :: "'a set \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> bool" where
"idempotent A f \<equiv> \<forall>x\<in>A. (f \<circ> f) x = f x"
context order
begin
lemma eq_refl: "\<lbrakk>x \<in> carrier A; x = x\<rbrakk> \<Longrightarrow> x \<sqsubseteq> x" by (metis order_refl)
subsection {* Least upper bounds *}
definition is_ub :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_ub x X \<equiv> (X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. y \<sqsubseteq> x)"
definition is_lub :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_lub x X \<equiv> is_ub x X \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. z \<sqsubseteq> y) \<longrightarrow> x \<sqsubseteq> y)"
lemma is_lub_simp: "is_lub x X = ((X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. y \<sqsubseteq> x) \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. z \<sqsubseteq> y) \<longrightarrow> x \<sqsubseteq> y))"
by (simp add: is_lub_def is_ub_def)
lemma is_lub_unique: "is_lub x X \<longrightarrow> is_lub y X \<longrightarrow> x = y"
by (smt order_antisym is_lub_def is_ub_def)
definition lub :: "'a set \<Rightarrow> 'a" ("\<Sigma>") where
"\<Sigma> X = (THE x. is_lub x X)"
lemma lub_simp: "\<Sigma> X = (THE x. (X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. y \<sqsubseteq> x) \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. z \<sqsubseteq> y) \<longrightarrow> x \<sqsubseteq> y))"
by (simp add: lub_def is_lub_simp)
lemma the_lub_leq: "\<lbrakk>\<exists>z. is_lub z X; \<And>z. is_lub z X \<longrightarrow> z \<sqsubseteq> x\<rbrakk> \<Longrightarrow> \<Sigma> X \<sqsubseteq> x"
by (metis is_lub_unique lub_def the_equality)
lemma the_lub_geq: "\<lbrakk>\<exists>z. is_lub z X; \<And>z. is_lub z X \<Longrightarrow> x \<sqsubseteq> z\<rbrakk> \<Longrightarrow> x \<sqsubseteq> \<Sigma> X"
by (metis is_lub_unique lub_def the_equality)
lemma lub_is_lub [elim?]: "is_lub w X \<Longrightarrow> \<Sigma> X = w"
by (metis is_lub_unique lub_def the_equality)
lemma singleton_lub: "y \<in> carrier A \<Longrightarrow> \<Sigma> {y} = y"
by (unfold lub_def, rule the_equality, simp_all add: is_lub_def is_ub_def, metis order_antisym order_refl)
lemma surjective_lub: "\<forall>y\<in>carrier A. \<exists>X\<subseteq>carrier A. y = \<Sigma> X"
by (metis bot_least insert_subset singleton_lub)
lemma lub_subset: "\<lbrakk>X \<subseteq> Y; is_lub x X; is_lub y Y\<rbrakk> \<Longrightarrow> x \<sqsubseteq> y"
by (metis (no_types) is_lub_def is_ub_def set_rev_mp)
lemma lub_closed: "\<lbrakk>X \<subseteq> carrier A; \<exists>x. is_lub x X\<rbrakk> \<Longrightarrow> \<Sigma> X \<in> carrier A"
by (rule_tac ?P = "\<lambda>x. is_lub x X" in the1I2, metis is_lub_unique, metis is_lub_def is_ub_def lub_is_lub)
definition join :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<squnion>" 70) where
"x \<squnion> y = \<Sigma> {x,y}"
subsection {* Greatest lower bounds *}
definition is_lb :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_lb x X \<equiv> (X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. x \<sqsubseteq> y)"
definition is_glb :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_glb x X \<longleftrightarrow> is_lb x X \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. y \<sqsubseteq> z) \<longrightarrow> y \<sqsubseteq> x)"
lemma is_glb_simp: "is_glb x X = ((X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. x \<sqsubseteq> y) \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. y \<sqsubseteq> z) \<longrightarrow> y \<sqsubseteq> x))"
by (simp add: is_glb_def is_lb_def)
lemma is_glb_unique: "is_glb x X \<longrightarrow> is_glb y X \<longrightarrow> x = y"
by (smt order_antisym is_glb_def is_lb_def)
definition glb :: "'a set \<Rightarrow> 'a" ("\<Pi>") where
"\<Pi> X = (THE x. is_glb x X)"
lemma glb_simp: "\<Pi> X = (THE x. (X \<subseteq> carrier A) \<and> (x \<in> carrier A) \<and> (\<forall>y\<in>X. x \<sqsubseteq> y) \<and> (\<forall>y\<in>carrier A.(\<forall>z\<in>X. y \<sqsubseteq> z) \<longrightarrow> y \<sqsubseteq> x))"
by (simp add: glb_def is_glb_simp)
lemma the_glb_geq: "\<lbrakk>\<exists>z. is_glb z X; \<And>z. is_glb z X \<longrightarrow> x \<sqsubseteq> z\<rbrakk> \<Longrightarrow> x \<sqsubseteq> \<Pi> X"
by (metis glb_def is_glb_unique the_equality)
lemma the_glb_leq: "\<lbrakk>\<exists>z. is_glb z X; \<And>z. is_glb z X \<longrightarrow> z \<sqsubseteq> x\<rbrakk> \<Longrightarrow> \<Pi> X \<sqsubseteq> x"
by (metis glb_def is_glb_unique the_equality)
lemma glb_is_glb [elim?]: "is_glb w X \<Longrightarrow> \<Pi> X = w"
by (metis is_glb_unique glb_def the_equality)
lemma singleton_glb: "y \<in> carrier A \<Longrightarrow> \<Pi> {y} = y"
by (unfold glb_def, rule the_equality, simp_all add: is_glb_def is_lb_def, metis order_antisym order_refl)
lemma surjective_glb: "\<forall>y\<in>carrier A. \<exists>X\<subseteq>carrier A. y = \<Pi> X"
by (metis bot_least insert_subset singleton_glb)
lemma glb_subset: "\<lbrakk>X \<subseteq> Y; is_glb x X; is_glb y Y\<rbrakk> \<Longrightarrow> y \<sqsubseteq> x"
by (metis (no_types) in_mono is_glb_def is_lb_def)
lemma glb_closed: "\<lbrakk>X \<subseteq> carrier A; \<exists>x. is_glb x X\<rbrakk> \<Longrightarrow> \<Pi> X \<in> carrier A"
by (rule_tac ?P = "\<lambda>x. is_glb x X" in the1I2, metis is_glb_unique, metis is_glb_def is_lb_def glb_is_glb)
definition meet :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "\<sqinter>" 70) where
"x \<sqinter> y = \<Pi> {x,y}"
definition less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<sqsubset>" 50) where
"x \<sqsubset> y \<equiv> (x \<sqsubseteq> y \<and> x \<noteq> y)"
lemma less_irrefl [iff]: "x \<in> carrier A \<Longrightarrow> \<not> x \<sqsubset> x"
by (simp add: less_def)
lemma less_imp_le: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubset> y\<rbrakk> \<Longrightarrow> x \<sqsubseteq> y"
by (simp add: less_def)
lemma less_asym: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubset> y; (\<not> P \<Longrightarrow> y \<sqsubset> x)\<rbrakk> \<Longrightarrow> P"
by (metis order_antisym less_def)
lemma less_trans: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A; x \<sqsubset> y; y \<sqsubset> z\<rbrakk> \<Longrightarrow> x \<sqsubset> z"
by (metis less_asym less_def order_trans)
lemma less_le_trans: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A; x \<sqsubset> y; y \<sqsubseteq> z\<rbrakk> \<Longrightarrow> x \<sqsubset> z"
by (metis less_def less_trans)
lemma less_asym': "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubset> y; y \<sqsubset> x\<rbrakk> \<Longrightarrow> P"
by (metis less_asym)
lemma le_imp_less_or_eq: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> x \<sqsubset> y \<or> x = y"
by (metis less_def)
lemma less_imp_not_less: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubset> y\<rbrakk> \<Longrightarrow> (\<not> y \<sqsubset> x) \<longleftrightarrow> True"
by (metis less_asym)
lemma less_imp_triv: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubset> y\<rbrakk> \<Longrightarrow> (y \<sqsubset> x \<longrightarrow> P) \<longleftrightarrow> True"
by (metis less_asym)
definition coclosure :: "('a \<Rightarrow> 'a) \<Rightarrow> bool" where
"coclosure m \<equiv> (m \<in> carrier A \<rightarrow> carrier A) \<and> (\<forall>x\<in>carrier A. \<forall>y\<in>carrier A. x \<sqsubseteq> y \<longrightarrow> m x \<sqsubseteq> m y)
\<and> (\<forall>x\<in>carrier A. m x \<sqsubseteq> x)
\<and> (\<forall>x\<in>carrier A. m x \<sqsubseteq> m (m x))"
definition is_max :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_max x X \<equiv> x \<in> X \<and> (\<forall>y\<in>X. y \<sqsubseteq> x)"
definition is_min :: "'a \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_min x X \<equiv> x \<in> X \<and> (\<forall>y\<in>X. x \<sqsubseteq> y)"
lemma is_max_equiv: "X \<subseteq> carrier A \<Longrightarrow> is_max x X = (x \<in> X \<and> is_lub x X)"
by (simp add: is_lub_simp, safe, (metis is_max_def set_mp)+)
lemma is_min_equiv: "X \<subseteq> carrier A \<Longrightarrow> is_min x X = (x \<in> X \<and> is_glb x X)"
by (simp add: is_glb_simp, safe, (metis is_min_def set_mp)+)
definition way_below :: "'a \<Rightarrow> 'a \<Rightarrow> prop" (infixl "\<guillemotleft>" 50) where
"x \<guillemotleft> y \<equiv> (\<And>D. \<lbrakk>D \<subseteq> carrier A; \<forall>a\<in>D. \<forall>b\<in>D. \<exists>c\<in>D. a \<sqsubseteq> c \<and> b \<sqsubseteq> c; \<exists>z. is_lub z D; y \<sqsubseteq> \<Sigma> D\<rbrakk> \<Longrightarrow> \<exists>z\<in>D. x \<sqsubseteq> z)"
lemma way_below_leq:
assumes xc: "x \<in> carrier A" and yc: "y \<in> carrier A" and x_below_y: "x \<guillemotleft> y"
shows "x \<sqsubseteq> y"
proof -
have "\<And>D. \<lbrakk>D \<subseteq> carrier A; \<forall>a\<in>D. \<forall>b\<in>D. \<exists>c\<in>D. a \<sqsubseteq> c \<and> b \<sqsubseteq> c; \<exists>z. is_lub z D; y \<sqsubseteq> \<Sigma> D\<rbrakk> \<Longrightarrow> \<exists>z\<in>D. x \<sqsubseteq> z"
by (insert x_below_y, simp add: way_below_def)
hence "\<lbrakk>{y} \<subseteq> carrier A; \<forall>a\<in>{y}. \<forall>b\<in>{y}. \<exists>c\<in>{y}. a \<sqsubseteq> c \<and> b \<sqsubseteq> c; \<exists>z. is_lub z {y}; y \<sqsubseteq> \<Sigma> {y}\<rbrakk> \<Longrightarrow> \<exists>z\<in>{y}. x \<sqsubseteq> z"
by auto
moreover have "{y} \<subseteq> carrier A"
by (metis empty_subsetI insert_subset yc)
moreover have "\<forall>a\<in>{y}. \<forall>b\<in>{y}. \<exists>c\<in>{y}. a \<sqsubseteq> c \<and> b \<sqsubseteq> c"
by (metis order_refl singletonE yc)
moreover have "\<exists>z. is_lub z {y}"
by (rule_tac x = y in exI, simp add: is_lub_simp, metis order_refl yc)
moreover have "y \<sqsubseteq> \<Sigma> {y}"
by (metis eq_refl singleton_lub yc)
ultimately show "x \<sqsubseteq> y"
by (metis singleton_iff)
qed
definition compact :: "'a \<Rightarrow> prop" where
"compact x \<equiv> x \<guillemotleft> x"
definition covers_op :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "covers" 50) where
"y covers x \<equiv> x \<sqsubset> y \<and> \<not> (\<exists>z. x \<sqsubset> z \<and> z \<sqsubset> y)"
end
definition pointwise_extension :: "'a ord \<Rightarrow> ('b \<Rightarrow> 'a) ord" ("\<up>") where
"pointwise_extension ord = \<lparr>carrier = UNIV \<rightarrow> carrier ord, le = \<lambda>f g. \<forall>x. le ord (f x) (g x)\<rparr>"
lemma extend_ord: "order A \<Longrightarrow> order (\<up> A)"
apply default
apply (simp_all add: pointwise_extension_def)
apply (metis UNIV_I ftype_pred order.order_refl)
apply (metis UNIV_I ftype_pred order.order_trans)
apply default
by (metis UNIV_I ftype_pred order.order_antisym)
lemma extend_dual: "\<up> (A\<sharp>) = (\<up> A)\<sharp>"
by (simp add: pointwise_extension_def ord_inv_def)
lemma dual_is_max: "order A \<Longrightarrow> order.is_max (A\<sharp>) x X = order.is_min A x X"
by (simp add: order.is_max_def order.is_min_def)
lemma dual_is_min: "order A \<Longrightarrow> order.is_min (A\<sharp>) x X = order.is_max A x X"
by (simp add: order.is_max_def order.is_min_def)
abbreviation less_ext :: "'a \<Rightarrow> ('a, 'b) ord_scheme \<Rightarrow> 'a \<Rightarrow> bool" ("_\<sqsubset>\<^bsub>_\<^esub>_" [51,0,51] 50) where
"x \<sqsubset>\<^bsub>A\<^esub> y \<equiv> order.less A x y"
abbreviation lub_ext :: "('a, 'b) ord_scheme \<Rightarrow> 'a set \<Rightarrow> 'a" ("\<Sigma>\<^bsub>_\<^esub>_" [0,1000] 100) where
"\<Sigma>\<^bsub>A\<^esub>X \<equiv> order.lub A X"
abbreviation glb_ext :: "('a, 'b) ord_scheme \<Rightarrow> 'a set \<Rightarrow> 'a" ("\<Pi>\<^bsub>_\<^esub>_" [0,1000] 100) where
"\<Pi>\<^bsub>A\<^esub>X \<equiv> order.glb A X"
abbreviation join_ext :: "'a \<Rightarrow> ('a, 'b) ord_scheme \<Rightarrow> 'a \<Rightarrow> 'a" ("_ \<squnion>\<^bsub>_\<^esub> _" [71,0,70] 70) where
"x \<squnion>\<^bsub>A\<^esub> y \<equiv> order.join A x y"
abbreviation meet_ext :: "'a \<Rightarrow> ('a, 'b) ord_scheme \<Rightarrow> 'a \<Rightarrow> 'a" ("_ \<sqinter>\<^bsub>_\<^esub> _" [70,0,70] 70) where
"x \<sqinter>\<^bsub>A\<^esub> y \<equiv> order.meet A x y"
subsection {* Join and meet preserving functions *}
definition ex_join_preserving :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"ex_join_preserving A B f \<equiv> order A \<and> order B \<and> (\<forall>X\<subseteq>carrier A. ((\<exists>x\<in>carrier A. order.is_lub A x X) \<longrightarrow> order.lub B (f ` X) = f (order.lub A X)))"
definition ex_meet_preserving :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"ex_meet_preserving A B f \<equiv> order A \<and> order B \<and> (\<forall>X\<subseteq>carrier A. ((\<exists>x\<in>carrier A. order.is_glb A x X) \<longrightarrow> order.glb B (f ` X) = f (order.glb A X)))"
definition join_preserving :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"join_preserving A B f \<equiv> order A \<and> order B \<and> (\<forall>X\<subseteq>carrier A. order.lub B (f ` X) = f (order.lub A X))"
definition meet_preserving :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"meet_preserving A B g \<equiv> order A \<and> order B \<and> (\<forall>X\<subseteq>carrier A. order.glb B (g ` X) = g (order.glb A X))"
definition directed :: "('a, 'b) ord_scheme \<Rightarrow> bool" where
"directed A \<equiv> order A \<and> (\<forall>x\<in>carrier A. \<forall>y\<in>carrier A. \<exists>z\<in>carrier A. x \<sqsubseteq>\<^bsub>A\<^esub> z \<and> y \<sqsubseteq>\<^bsub>A\<^esub> z)"
definition scott_continuous :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" where
"scott_continuous A B f \<equiv> (\<forall>D\<subseteq>carrier A. ((directed \<lparr>carrier = D, le = op \<sqsubseteq>\<^bsub>A\<^esub>\<rparr>) \<longrightarrow> order.lub B (f ` D) = f (order.lub A D)))"
definition scott_ne_continuous :: "('a, 'c) ord_scheme \<Rightarrow> ('b, 'd) ord_scheme \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> prop" where
"scott_ne_continuous A B f \<equiv> (\<And>D. \<lbrakk>D \<subseteq> carrier A; directed \<lparr>carrier = D, le = op \<sqsubseteq>\<^bsub>A\<^esub>, \<dots> = ord.more A\<rparr>; D \<noteq> {}\<rbrakk> \<Longrightarrow> \<Sigma>\<^bsub>B\<^esub>(f ` D) = f (\<Sigma>\<^bsub>A\<^esub>D))"
lemma dual_is_lub [simp]: "order A \<Longrightarrow> order.is_lub (A\<sharp>) x X = order.is_glb A x X"
by (simp add: order.is_glb_simp order.is_lub_simp)
lemma dual_is_ub [simp]: "order A \<Longrightarrow> order.is_ub (A\<sharp>) x X = order.is_lb A x X"
by (simp add: order.is_lb_def order.is_ub_def)
lemma dual_is_glb [simp]: "order A \<Longrightarrow> order.is_glb (A\<sharp>) x X = order.is_lub A x X"
by (simp add: order.is_glb_simp order.is_lub_simp)
lemma dual_is_lb [simp]: "order A \<Longrightarrow> order.is_lb (A\<sharp>) x X = order.is_ub A x X"
by (simp add: order.is_lb_def order.is_ub_def)
lemma dual_lub [simp]: "order A \<Longrightarrow> \<Sigma>\<^bsub>A\<sharp>\<^esub>X = \<Pi>\<^bsub>A\<^esub>X"
by (simp add: order.glb_simp order.lub_simp)
lemma dual_glb [simp]: "order A \<Longrightarrow> \<Pi>\<^bsub>A\<sharp>\<^esub>X = \<Sigma>\<^bsub>A\<^esub>X"
by (simp add: order.glb_simp order.lub_simp)
lemma common: "\<lbrakk>A \<Longrightarrow> P = Q\<rbrakk> \<Longrightarrow> (A \<and> P) = (A \<and> Q)" by metis
lemma dual_ex_join_preserving [simp]: "ex_join_preserving (A\<sharp>) (B\<sharp>) f = ex_meet_preserving A B f"
by (simp add: ex_meet_preserving_def ex_join_preserving_def, (rule common)+, simp)
lemma dual_ex_meet_preserving [simp]: "ex_meet_preserving (A\<sharp>) (B\<sharp>) f = ex_join_preserving A B f"
by (simp add: ex_meet_preserving_def ex_join_preserving_def, (rule common)+, simp)
lemma dual_join_preserving [simp]: "join_preserving (A\<sharp>) (B\<sharp>) f = meet_preserving A B f"
by (simp add: meet_preserving_def join_preserving_def, (rule common)+, simp)
lemma dual_meet_preserving [simp]: "meet_preserving (A\<sharp>) (B\<sharp>) f = join_preserving A B f"
by (simp add: meet_preserving_def join_preserving_def, (rule common)+, simp)
hide_fact common
(* +------------------------------------------------------------------------+ *)
subsection {* Total orders *}
(* +------------------------------------------------------------------------+ *)
locale total_order = order +
assumes totality: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqsubseteq> y \<or> y \<sqsubseteq> x"
lemma total_order_is_directed: "total_order A \<Longrightarrow> directed A"
apply (simp add: directed_def, safe)
apply (simp add: total_order_def)
by (metis total_order.totality)
lemma dual_total_order: "total_order A \<longleftrightarrow> total_order (A\<sharp>)"
by (simp add: total_order_def total_order_axioms_def, auto)
context total_order
begin
lemma is_max_unique: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; X \<subseteq> carrier A; is_max x X; is_max y X\<rbrakk> \<Longrightarrow> x = y"
by (metis is_max_def order_antisym)
lemma is_min_unique: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; X \<subseteq> carrier A; is_min x X; is_min y X\<rbrakk> \<Longrightarrow> x = y"
by (metis is_min_def order_antisym)
lemma no_max_equiv: "X \<subseteq> carrier A \<Longrightarrow> (\<forall>x\<in>X. \<exists>y\<in>X. x \<sqsubset> y) \<longleftrightarrow> (\<forall>x\<in>carrier A. \<not> is_max x X)"
by (smt in_mono is_max_def less_def order_antisym totality)
lemma no_min_equiv: "X \<subseteq> carrier A \<Longrightarrow> (\<forall>x\<in>X. \<exists>y\<in>X. y \<sqsubset> x) \<longleftrightarrow> (\<forall>x\<in>carrier A. \<not> is_min x X)"
by (smt is_min_def less_def order_antisym subsetD totality)
lemma finite_max_var: "\<lbrakk>X \<subseteq> carrier A; finite X; y \<in> carrier A\<rbrakk> \<Longrightarrow> (\<exists>x\<in>(insert y X). is_max x (insert y X))"
apply (rule finite_subset_induct_var[of X "carrier A"])
apply (metis, metis)
apply (rule_tac x = y in bexI)
apply (simp add: is_max_def)
apply (metis singleton_iff)
proof -
fix a F assume ac: "a \<in> carrier A" and F_subset: "F \<subseteq> carrier A" and yc: "y \<in> carrier A"
and "\<exists>x\<in>insert y F. is_max x (insert y F)"
then obtain x where f: "is_max x (insert y F)" by auto
thus "\<exists>x\<in>insert y (insert a F). is_max x (insert y (insert a F))"
apply (cases "x \<sqsubseteq> a")
apply (rule_tac x = a in bexI)
apply (smt ac F_subset yc insert_iff is_max_def order_refl order_trans set_rev_mp)
apply (simp add: is_max_def)
apply (rule_tac x = x in bexI)
apply (smt ac F_subset yc insert_iff is_max_def set_rev_mp totality)
by (simp add: is_max_def, auto)
qed
lemma finite_max: "\<lbrakk>X \<subseteq> carrier A; finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> \<exists>x. is_max x X"
by (metis finite_max_var insert_absorb2 insert_subset nonempty_iff)
lemma finite_min:
assumes subset: "X \<subseteq> carrier A" and finite: "finite X" and non_empty: "X \<noteq> {}"
shows "\<exists>x. is_min x X"
proof -
have "total_order A"
by unfold_locales
hence "total_order (A\<sharp>)"
by (metis (lifting) dual_total_order)
hence "\<exists>x. order.is_max (A\<sharp>) x X"
by (metis finite inv_carrier_id non_empty subset total_order.finite_max)
thus "\<exists>x. is_min x X"
by (metis `total_order (A\<sharp>)` directed_def dual_is_min inv_inv_id total_order_is_directed)
qed
end
(* +------------------------------------------------------------------------+ *)
subsection {* Join semilattices *}
(* +------------------------------------------------------------------------+ *)
locale join_semilattice = order +
assumes join_ex: "\<lbrakk>x \<in> carrier A; y\<in>carrier A\<rbrakk> \<Longrightarrow> \<exists>z\<in>carrier A. is_lub z {x,y}"
context join_semilattice
begin
lemma leq_def: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> (x \<sqsubseteq> y) \<longleftrightarrow> (x \<squnion> y = y)"
apply (simp add: join_def lub_def)
proof
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and xy: "x \<sqsubseteq> y"
show "(THE z. is_lub z {x,y}) = y"
by (rule the_equality, simp_all add: is_lub_def is_ub_def, safe, (metis x_closed y_closed xy order_refl order_antisym)+)
next
assume "x \<in> carrier A" and "y \<in> carrier A" and "(THE z. is_lub z {x,y}) = y"
thus "x \<sqsubseteq> y"
by (metis insertCI is_lub_def is_ub_def join_ex lub_def lub_is_lub)
qed
lemma leq_def_right: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> (x \<squnion> y = y)"
by (metis leq_def)
lemma leq_def_left: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; x \<squnion> y = y\<rbrakk> \<Longrightarrow> (x \<sqsubseteq> y)"
by (metis leq_def)
lemma join_idem: "\<lbrakk>x \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> x = x" by (metis leq_def order_refl)
lemma join_comm: "x \<squnion> y = y \<squnion> x" by (metis insert_commute join_def)
lemma bin_lub_var: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> y \<sqsubseteq> z \<longleftrightarrow> x \<sqsubseteq> z \<and> y \<sqsubseteq> z"
proof
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
and join_le_z: "x \<squnion> y \<sqsubseteq> z"
have "x \<sqsubseteq> z" using join_le_z
apply (simp add: join_def lub_def)
apply (rule_tac ?P = "\<lambda>z. is_lub z {x,y}" in the1I2)
apply (metis join_ex lub_is_lub x_closed y_closed)
by (smt insertI1 is_lub_def is_ub_def join_def join_le_z lub_is_lub order_trans x_closed z_closed)
moreover have "y \<sqsubseteq> z" using join_le_z
apply (simp add: join_def lub_def)
apply (rule_tac ?P = "\<lambda>z. is_lub z {x,y}" in the1I2)
apply (metis join_ex lub_is_lub x_closed y_closed)
by (smt insert_iff is_lub_def is_ub_def join_def join_le_z lub_is_lub order_trans y_closed z_closed)
ultimately show "x \<sqsubseteq> z \<and> y \<sqsubseteq> z" by auto
next
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
and xz_and_yz: "x \<sqsubseteq> z \<and> y \<sqsubseteq> z"
thus "x \<squnion> y \<sqsubseteq> z"
by (smt emptyE lub_is_lub insertE is_lub_def is_ub_def join_ex join_def ord_le_eq_trans)
qed
lemma join_closed: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> y \<in> carrier A"
by (metis join_def join_ex lub_is_lub)
lemma join_assoc: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> (x \<squnion> y) \<squnion> z = x \<squnion> (y \<squnion> z)"
proof -
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
hence "(x \<squnion> y) \<squnion> z \<sqsubseteq> x \<squnion> (y \<squnion> z)"
by (metis eq_refl bin_lub_var join_closed)
thus ?thesis
by (smt join_closed order_antisym bin_lub_var order_refl x_closed y_closed z_closed)
qed
end
lemma ex_join_preserving_is_iso:
assumes f_closed: "f \<in> carrier A \<rightarrow> carrier B"
and js_A: "join_semilattice A" and js_B: "join_semilattice B"
and join_pres: "ex_join_preserving A B f"
shows "isotone A B f"
proof -
have ord_A: "order A" and ord_B: "order B"
by (metis ex_join_preserving_def join_pres)+
have "\<forall>x y. x \<sqsubseteq>\<^bsub>A\<^esub> y \<and> x \<in> carrier A \<and> y \<in> carrier A \<longrightarrow> f x \<sqsubseteq>\<^bsub>B\<^esub> f y"
proof clarify
fix x y assume xy: "x \<sqsubseteq>\<^bsub>A\<^esub> y" and xc: "x \<in> carrier A" and yc: "y \<in> carrier A"
have xyc: "{x,y} \<subseteq> carrier A"
by (metis bot_least insert_subset xc yc)
have ejp: "\<forall>X\<subseteq>carrier A. ((\<exists>x\<in>carrier A. order.is_lub A x X) \<longrightarrow> \<Sigma>\<^bsub>B\<^esub>(f`X) = f (\<Sigma>\<^bsub>A\<^esub>X))"
by (metis ex_join_preserving_def join_pres)
have "\<exists>z\<in>carrier A. order.is_lub A z {x,y}"
by (metis join_semilattice.join_ex js_A xc yc)
hence xy_join_pres: "f (\<Sigma>\<^bsub>A\<^esub>{x,y}) = \<Sigma>\<^bsub>B\<^esub>{f x, f y}"
by (metis ejp xyc image_empty image_insert)
have "f (\<Sigma>\<^bsub>A\<^esub>{x,y}) = f y"
by (rule_tac f = f in arg_cong, metis ord_A order.join_def join_semilattice.leq_def_right js_A xc xy yc)
hence "\<Sigma>\<^bsub>B\<^esub>{f x, f y} = f y"
by (metis xy_join_pres)
thus "f x \<sqsubseteq>\<^bsub>B\<^esub> f y"
by (smt join_semilattice.leq_def_left js_B typed_application f_closed xc yc ord_B order.join_def)
qed
thus ?thesis by (metis isotone_def ord_A ord_B)
qed
lemma helper: "\<lbrakk>\<And>x. P x \<and> Q x\<rbrakk> \<Longrightarrow> (\<forall>x. P x) \<and> (\<forall>x. Q x)" by fast
lemma extend_binlub:
assumes js_A: "join_semilattice A"
and fc: "f \<in> carrier (\<up> A)" and gc: "g \<in> carrier (\<up> A)"
shows "order.is_lub (\<up> A) (\<lambda>x. f x \<squnion>\<^bsub>A\<^esub> g x) {f, g}"
proof -
have ord_A_ex: "order (\<up> A)"
by (insert js_A, simp add: join_semilattice_def, metis extend_ord)
let ?L = "\<lambda>x. f x \<squnion>\<^bsub>A\<^esub> g x"
have Lc: "?L \<in> carrier (\<up> A)"
apply (simp add: pointwise_extension_def, rule typed_abstraction)
by (smt UNIV_I assms fc gc join_semilattice.join_closed partial_object.simps(1) pointwise_extension_def typed_application)
have "f \<sqsubseteq>\<^bsub>\<up> A\<^esub> ?L \<and> g \<sqsubseteq>\<^bsub>\<up> A\<^esub> ?L"
proof (simp add: pointwise_extension_def, rule helper)
fix x
have fx: "f x \<in> carrier A" and gx: "g x \<in> carrier A"
by (smt UNIV_I fc gc partial_object.simps(1) pointwise_extension_def typed_application)+
hence Lx: "?L x \<in> carrier A"
by (metis assms join_semilattice.join_closed)
show "f x \<sqsubseteq>\<^bsub>A\<^esub> ?L x \<and> g x \<sqsubseteq>\<^bsub>A\<^esub> ?L x"
apply (simp add: join_semilattice.leq_def[OF js_A fx Lx] join_semilattice.leq_def[OF js_A gx Lx])
apply (intro conjI)
by (smt assms fx gx join_semilattice.join_assoc join_semilattice.join_idem join_semilattice.join_comm)+
qed
moreover hence "\<forall>h\<in>carrier (\<up> A). f \<sqsubseteq>\<^bsub>\<up> A\<^esub> h \<and> g \<sqsubseteq>\<^bsub>\<up> A\<^esub> h \<longrightarrow> ?L \<sqsubseteq>\<^bsub>\<up> A\<^esub> h"
apply (simp add: pointwise_extension_def)
by (smt UNIV_I assms fc gc join_semilattice.bin_lub_var partial_object.simps(1) pointwise_extension_def typed_application)
ultimately show ?thesis
by (simp add: order.is_lub_simp[OF ord_A_ex], safe, (metis fc gc Lc)+)
qed
lemma extend_join:
assumes js_A: "join_semilattice A"
and fc: "f \<in> carrier (\<up> A)" and gc: "g \<in> carrier (\<up> A)"
shows "f \<squnion>\<^bsub>\<up> A\<^esub> g = (\<lambda>x. f x \<squnion>\<^bsub>A\<^esub> g x)"
proof -
have ord_A_ex: "order (\<up> A)"
by (insert js_A, simp add: join_semilattice_def, metis extend_ord)
show ?thesis
apply (insert extend_binlub[OF js_A fc gc])
by (simp add: order.join_def[OF ord_A_ex], metis ord_A_ex order.lub_is_lub)
qed
lemma extend_js:
assumes js_A: "join_semilattice A"
shows "join_semilattice (\<up> A)"
proof (simp add: join_semilattice_def join_semilattice_axioms_def, safe)
show ord_A_ex: "order (\<up> A)"
by (insert js_A, simp add: join_semilattice_def, metis extend_ord)
fix f g :: "'b \<Rightarrow> 'a" assume fc: "f \<in> carrier (\<up> A)" and gc: "g \<in> carrier (\<up> A)"
thus "\<exists>h\<in>carrier (\<up> A). order.is_lub (\<up> A) h {f, g}"
by (smt assms extend_binlub ord_A_ex order.is_lub_simp)
qed
(* +------------------------------------------------------------------------+ *)
subsection {* Meet semilattices *}
(* +------------------------------------------------------------------------+ *)
locale meet_semilattice = order +
assumes meet_ex: "\<lbrakk>x \<in> carrier A; y\<in>carrier A\<rbrakk> \<Longrightarrow> \<exists>z\<in>carrier A. is_glb z {x,y}"
context meet_semilattice
begin
lemma leq_meet_def: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> (x \<sqsubseteq> y) \<longleftrightarrow> (x \<sqinter> y = x)"
apply (simp add: meet_def glb_def)
proof
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and xy: "x \<sqsubseteq> y"
show "(THE z. is_glb z {x,y}) = x"
by (rule the_equality, simp_all add: is_glb_def is_lb_def, safe, (metis x_closed y_closed xy order_refl order_antisym)+)
next
assume "x \<in> carrier A" and "y \<in> carrier A" and "(THE z. is_glb z {x,y}) = x"
thus "x \<sqsubseteq> y"
by (metis insertCI is_glb_def is_lb_def meet_ex glb_def glb_is_glb)
qed
lemma meet_idem: "\<lbrakk>x \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqinter> x = x" by (metis leq_meet_def order_refl)
lemma meet_comm: "x \<sqinter> y = y \<sqinter> x" by (metis insert_commute meet_def)
lemma bin_glb_var: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> z \<sqsubseteq> x \<sqinter> y \<longleftrightarrow> z \<sqsubseteq> x \<and> z \<sqsubseteq> y"
proof
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
and meet_le_z: "z \<sqsubseteq> x \<sqinter> y"
have "z \<sqsubseteq> x" using meet_le_z
apply (simp add: meet_def glb_def)
apply (rule_tac ?P = "\<lambda>z. is_glb z {x,y}" in the1I2)
apply (metis meet_ex glb_is_glb x_closed y_closed)
by (smt insertI1 is_glb_def is_lb_def meet_def meet_le_z glb_is_glb order_trans x_closed z_closed)
moreover have "z \<sqsubseteq> y" using meet_le_z
apply (simp add: meet_def glb_def)
apply (rule_tac ?P = "\<lambda>z. is_glb z {x,y}" in the1I2)
apply (metis meet_ex glb_is_glb x_closed y_closed)
by (smt insert_iff is_glb_def is_lb_def meet_def meet_le_z glb_is_glb order_trans y_closed z_closed)
ultimately show "z \<sqsubseteq> x \<and> z \<sqsubseteq> y" by auto
next
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
and xz_and_yz: "z \<sqsubseteq> x \<and> z \<sqsubseteq> y"
thus "z \<sqsubseteq> x \<sqinter> y"
by (smt emptyE glb_is_glb insertE is_glb_def is_lb_def meet_ex meet_def ord_le_eq_trans)
qed
lemma meet_closed: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqinter> y \<in> carrier A"
by (metis meet_def meet_ex glb_is_glb)
lemma meet_assoc: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> (x \<sqinter> y) \<sqinter> z = x \<sqinter> (y \<sqinter> z)"
proof -
assume x_closed: "x \<in> carrier A" and y_closed: "y \<in> carrier A" and z_closed: "z \<in> carrier A"
hence "(x \<sqinter> y) \<sqinter> z \<sqsubseteq> x \<sqinter> (y \<sqinter> z)"
by (metis eq_refl bin_glb_var meet_closed)
thus ?thesis
by (smt meet_closed order_antisym bin_glb_var order_refl x_closed y_closed z_closed)
qed
end
lemma inv_meet_semilattice_is_join [simp]: "meet_semilattice (A\<sharp>) = join_semilattice A"
by (simp_all add: meet_semilattice_def join_semilattice_def meet_semilattice_axioms_def join_semilattice_axioms_def, safe, simp_all)
lemma inv_join_semilattice_is_meet [simp]: "join_semilattice (A\<sharp>) = meet_semilattice A"
by (simp add: meet_semilattice_def join_semilattice_def meet_semilattice_axioms_def join_semilattice_axioms_def, safe, simp_all)
lemma ex_meet_preserving_is_iso:
assumes f_closed: "f \<in> carrier A \<rightarrow> carrier B"
and js_A: "meet_semilattice A" and js_B: "meet_semilattice B"
and join_pres: "ex_meet_preserving A B f"
shows "isotone A B f"
proof -
have "isotone (A\<sharp>) (B\<sharp>) f"
by (rule ex_join_preserving_is_iso, simp_all add: f_closed js_A js_B join_pres)
thus "isotone A B f" by simp
qed
lemma extend_ms:
assumes ms_A: "meet_semilattice A"
shows "meet_semilattice (\<up> A)"
by (metis (lifting) assms extend_dual extend_js inv_join_semilattice_is_meet)
lemma extend_binglb:
assumes ms_A: "meet_semilattice A"
and fc: "f \<in> carrier (\<up> A)" and gc: "g \<in> carrier (\<up> A)"
shows "order.is_glb (\<up> A) (\<lambda>x. f x \<sqinter>\<^bsub>A\<^esub> g x) {f, g}"
proof -
have ord_A: "order A"
by (insert ms_A, simp add: meet_semilattice_def)
hence ord_A_ex: "order (\<up> A)"
by (metis extend_ord)
have "order.is_lub (\<up> (A\<sharp>)) (\<lambda>x. f x \<squnion>\<^bsub>A\<sharp>\<^esub> g x) {f, g}"
apply (rule extend_binlub)
apply (metis assms(1) inv_join_semilattice_is_meet)
apply (metis extend_dual fc inv_carrier_id)
by (metis extend_dual gc inv_carrier_id)
thus ?thesis using ord_A ord_A_ex
by (simp add: extend_dual order.join_def order.meet_def dual_is_lub[OF ord_A_ex])
qed
lemma extend_meet:
assumes ms_A: "meet_semilattice A"
and fc: "f \<in> carrier (\<up> A)" and gc: "g \<in> carrier (\<up> A)"
shows "f \<sqinter>\<^bsub>\<up> A\<^esub> g = (\<lambda>x. f x \<sqinter>\<^bsub>A\<^esub> g x)"
proof -
have ord_A_ex: "order (\<up> A)"
by (insert ms_A, simp add: meet_semilattice_def, metis extend_ord)
thus ?thesis
apply (insert extend_binglb[OF ms_A fc gc])
apply (simp add: order.meet_def[OF ord_A_ex])
by (metis ord_A_ex order.glb_is_glb)
qed
(* +------------------------------------------------------------------------+ *)
subsection {* Lattices *}
(* +------------------------------------------------------------------------+ *)
locale lattice = join_semilattice + meet_semilattice
begin
lemma absorb1: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> (x \<sqinter> y) = x"
by (metis join_comm leq_def leq_meet_def meet_assoc meet_closed meet_comm meet_idem)
lemma absorb2: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqinter> (x \<squnion> y) = x"
by (metis join_assoc join_closed join_comm join_idem leq_def leq_meet_def)
lemma order_change: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x\<sqinter>y = y \<longleftrightarrow> y\<squnion>x = x"
by (metis leq_def leq_meet_def meet_comm)
lemma bin_lub_insert:
assumes xc: "x \<in> carrier A" and X_subset: "X \<subseteq> carrier A"
and X_lub: "\<exists>y. is_lub y X"
shows "\<exists>z. is_lub z (insert x X)"
proof -
obtain y where y_lub: "is_lub y X" and yc: "y \<in> carrier A" by (metis X_lub is_lub_simp)
have "\<exists>z. is_lub z (insert x X)"
proof (intro exI conjI)
have "\<Sigma> {x, y} \<in> carrier A"
by (metis join_closed join_def xc yc)
thus "is_lub (\<Sigma> {x, y}) (insert x X)"
apply (simp add: is_lub_simp, safe)
apply (metis xc)
apply (metis X_subset set_mp)
apply (metis bin_lub_var join_def order_refl xc yc)
apply (metis (full_types) absorb2 bin_glb_var is_lub_simp join_comm join_def set_mp xc y_lub yc)
by (metis bin_lub_var is_lub_simp join_def xc y_lub)
qed
thus "\<exists>z. is_lub z (insert x X)"
by metis
qed
lemma set_induct: "\<lbrakk>X \<subseteq> carrier A; finite X; P {}; \<And>y Y. \<lbrakk>finite Y; y \<notin> Y; y \<in> carrier A; P Y\<rbrakk> \<Longrightarrow> P (insert y Y)\<rbrakk> \<Longrightarrow> P X"
by (metis (no_types) finite_subset_induct)
lemma finite_lub_var: "\<lbrakk>(insert x X) \<subseteq> carrier A; finite (insert x X)\<rbrakk> \<Longrightarrow> \<exists>z. is_lub z (insert x X)"
apply (rule_tac X = X and P = "\<lambda>X. \<exists>z. is_lub z (insert x X)" in set_induct)
apply (metis insert_subset)
apply (metis finite_insert)
apply (metis insert_absorb2 insert_subset join_ex)
apply (simp add: insert_commute)
apply (rule bin_lub_insert)
apply metis
apply (metis is_lub_simp)
by metis
lemma finite_lub: "\<lbrakk>X \<subseteq> carrier A; finite X; X \<noteq> {}\<rbrakk> \<Longrightarrow> \<exists>x. is_lub x X"
by (metis finite.simps finite_lub_var)
end
lemma inv_lattice [simp]: "lattice (A\<sharp>) = lattice A"
by (simp add: lattice_def, auto)
context lattice
begin
lemma finite_glb:
assumes "X \<subseteq> carrier A" and "finite X" and "X \<noteq> {}"
shows "\<exists>x. is_glb x X"
proof -
have ord_Ash: "order (A\<sharp>)"
by (simp, unfold_locales)
have "\<exists>x. order.is_lub (A\<sharp>) x X"
by (rule lattice.finite_lub, simp_all add: assms, unfold_locales)
thus "\<exists>x. is_glb x X"
by (insert ord_Ash, simp)
qed
lemma finite_lub_carrier:
assumes A_finite: "finite (carrier A)"
and A_non_empty: "carrier A \<noteq> {}"
and X_subset: "X \<subseteq> carrier A"
shows "\<exists>x. is_lub x X"
proof (cases "X = {}")
assume x_empty: "X = {}"
show "\<exists>x. is_lub x X"
proof (intro exI)
show "is_lub (\<Pi> (carrier A)) X"
by (metis (lifting) A_finite A_non_empty X_subset x_empty ex_in_conv finite_glb glb_is_glb is_glb_simp is_lub_def is_ub_def set_eq_subset)
qed
next
assume "X \<noteq> {}"
thus "\<exists>x. is_lub x X"
by (metis A_finite X_subset finite_lub rev_finite_subset)
qed
lemma finite_glb_carrier:
assumes A_finite: "finite (carrier A)"
and A_non_empty: "carrier A \<noteq> {}"
and X_subset: "X \<subseteq> carrier A"
shows "\<exists>x. is_glb x X"
proof -
have ord_Ash: "order (A\<sharp>)"
by (simp, unfold_locales)
have "\<exists>x. order.is_lub (A\<sharp>) x X"
by (rule lattice.finite_lub_carrier, simp_all add: assms, unfold_locales)
thus ?thesis by (insert ord_Ash, simp)
qed
end
lemma extend_lattice: "lattice A \<Longrightarrow> lattice (\<up> A)"
by (simp add: lattice_def extend_js extend_ms)
(* +------------------------------------------------------------------------+ *)
subsection {* Distributive Lattices *}
(* +------------------------------------------------------------------------+ *)
locale distributive_lattice = lattice +
assumes dist1: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqinter> (y \<squnion> z) = (x \<sqinter> y) \<squnion> (x \<sqinter> z)"
and dist2: "\<lbrakk>x \<in> carrier A; y \<in> carrier A; z \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> (y \<sqinter> z) = (x \<squnion> y) \<sqinter> (x \<squnion> z)"
lemma extend_distributive:
assumes dl_A: "distributive_lattice A"
shows "distributive_lattice (\<up> A)"
proof (simp add: distributive_lattice_def distributive_lattice_axioms_def, safe)
have "lattice A"
by (insert dl_A, simp add: distributive_lattice_def)
thus "lattice (\<up> A)"
by (metis extend_lattice)
hence ord_A_ex: "order (\<up> A)"
by (simp add: lattice_def join_semilattice_def, auto)
from `lattice A` have js_A: "join_semilattice A" and ms_A: "meet_semilattice A"
by (simp add: lattice_def)+
fix x y z :: "'d \<Rightarrow> 'a"
assume xc: "x \<in> carrier (\<up> A)" and yc: "y \<in> carrier (\<up> A)" and zc: "z \<in> carrier (\<up> A)"
hence yzj: "y \<squnion>\<^bsub>\<up>A\<^esub> z \<in> carrier (\<up> A)"
by (metis extend_js join_semilattice.join_closed js_A)
have xym: "x \<sqinter>\<^bsub>\<up>A\<^esub> y \<in> carrier (\<up> A)"
by (metis extend_ms meet_semilattice.meet_closed ms_A xc yc)
have xzm: "x \<sqinter>\<^bsub>\<up>A\<^esub> z \<in> carrier (\<up> A)"
by (metis extend_ms meet_semilattice.meet_closed ms_A xc zc)
from xc yc zc yzj xym xzm
show "x \<sqinter>\<^bsub>\<up> A\<^esub> (y \<squnion>\<^bsub>\<up> A\<^esub> z) = (x \<sqinter>\<^bsub>\<up> A\<^esub> y) \<squnion>\<^bsub>\<up> A\<^esub> (x \<sqinter>\<^bsub>\<up> A\<^esub> z)"
apply (simp add: extend_join[OF js_A] extend_meet[OF ms_A])
apply (simp add: pointwise_extension_def)
by (metis (hide_lams, no_types) UNIV_I assms distributive_lattice.dist1 typed_application)
hence yzm: "y \<sqinter>\<^bsub>\<up>A\<^esub> z \<in> carrier (\<up> A)"
by (metis extend_ms meet_semilattice.meet_closed ms_A yc zc)
have xyj: "x \<squnion>\<^bsub>\<up>A\<^esub> y \<in> carrier (\<up> A)"
by (metis extend_js join_semilattice.join_closed js_A xc yc)
have xzj: "x \<squnion>\<^bsub>\<up>A\<^esub> z \<in> carrier (\<up> A)"
by (metis extend_js join_semilattice.join_closed js_A xc zc)
from xc yc zc yzm xyj xzj
show "x \<squnion>\<^bsub>\<up> A\<^esub> (y \<sqinter>\<^bsub>\<up> A\<^esub> z) = (x \<squnion>\<^bsub>\<up> A\<^esub> y) \<sqinter>\<^bsub>\<up> A\<^esub> (x \<squnion>\<^bsub>\<up> A\<^esub> z)"
apply (simp add: extend_join[OF js_A] extend_meet[OF ms_A])
apply (simp add: pointwise_extension_def)
by (metis (hide_lams, no_types) UNIV_I assms distributive_lattice.dist2 typed_application)
qed
(* +------------------------------------------------------------------------+ *)
subsection {* Bounded Lattices *}
(* +------------------------------------------------------------------------+ *)
locale bounded_lattice = lattice +
assumes bot_ex: "\<exists>b\<in>carrier A. \<forall>x\<in>carrier A. b \<squnion> x = x"
and top_ex: "\<exists>t\<in>carrier A. \<forall>x\<in>carrier A. t \<sqinter> x = x"
context bounded_lattice
begin
definition bot :: "'a" ("\<bottom>") where "\<bottom> \<equiv> THE x. x\<in>carrier A \<and> (\<forall>y\<in>carrier A. x \<sqsubseteq> y)"
lemma bot_closed: "\<bottom> \<in> carrier A"
apply (simp add: bot_def)
apply (rule the1I2)
apply (metis (no_types) bot_ex leq_def_left order_antisym)
by auto
definition top :: "'a" ("\<top>") where "\<top> \<equiv> THE x. x\<in>carrier A \<and> (\<forall>y\<in>carrier A. y \<sqsubseteq> x)"
lemma top_closed: "\<top> \<in> carrier A"
apply (simp add: top_def)
apply (rule the1I2)
apply (metis (hide_lams, no_types) leq_meet_def meet_comm top_ex)
by auto
lemma bot_least: "x \<in> carrier A \<Longrightarrow> \<bottom> \<sqsubseteq> x"
apply (simp add: bot_def)
apply (rule the1I2)
apply (metis (no_types) bot_ex leq_def_left order_antisym)
by auto
lemma top_greatest: "x \<in> carrier A \<Longrightarrow> x \<sqsubseteq> \<top>"
apply (simp add: top_def)
apply (rule the1I2)
apply (metis (hide_lams, no_types) leq_meet_def meet_comm top_ex)
by auto
definition atom :: "'a \<Rightarrow> bool" where
"atom x \<equiv> x covers \<bottom>"
definition atoms :: "'a set" where
"atoms \<equiv> {x. x covers \<bottom> \<and> x \<in> carrier A}"
end
(* +------------------------------------------------------------------------+ *)
subsection {* Complemented Lattices *}
(* +------------------------------------------------------------------------+ *)
locale complemented_lattice = bounded_lattice +
assumes compl: "x \<in> carrier A \<Longrightarrow> \<exists>y. y \<in> carrier A \<and> x \<squnion> y = \<top> \<and> x \<sqinter> y = \<bottom>"
(* +------------------------------------------------------------------------+ *)
subsection {* Boolean algebra *}
(* +------------------------------------------------------------------------+ *)
datatype 'a ba_expr = BNand "'a ba_expr" "'a ba_expr"
| BOne
| BZero
| BAtom 'a
primrec be_atoms :: "'a ba_expr \<Rightarrow> 'a set" where
"be_atoms (BNand x y) = be_atoms x \<union> be_atoms y"
| "be_atoms BOne = {}"
| "be_atoms BZero = {}"
| "be_atoms (BAtom x) = {x}"
locale boolean_algebra = complemented_lattice + distributive_lattice
begin
lemma compl_uniq:
assumes xc: "x \<in> carrier A"
shows "\<exists>!y. y \<in> carrier A \<and> x \<squnion> y = \<top> \<and> x \<sqinter> y = \<bottom>"
apply safe
apply (metis assms compl)
by (metis absorb2 assms dist1 join_comm meet_comm)
definition complement :: "'a \<Rightarrow> 'a" ("!") where
"complement x = (THE y. y \<in> carrier A \<and> x \<squnion> y = \<top> \<and> x \<sqinter> y = \<bottom>)"
lemma complement_closed: assumes xc: "x \<in> carrier A" shows "!x \<in> carrier A"
by (simp add: complement_def, rule the1I2, rule compl_uniq[OF xc], auto)
primrec be_unfold :: "'a ba_expr \<Rightarrow> 'a" where
"be_unfold BOne = \<top>"
| "be_unfold BZero = \<bottom>"
| "be_unfold (BNand x y) = (! (be_unfold x \<squnion> be_unfold y))"
| "be_unfold (BAtom x) = x"
lemma atoms_closed: "atoms \<subseteq> carrier A"
by (auto simp add: atoms_def)
(*
lemma complement1: "x \<in> carrier A \<Longrightarrow> x \<squnion> !x = \<top>" sorry
lemma complement2: "x \<in> carrier A \<Longrightarrow> x \<sqinter> !x = \<bottom>" sorry
lemma not_one: "!\<top> = \<bottom>" sorry
lemma not_zero: "!\<bottom> = \<top>" sorry
lemma double_compl: "x \<in> carrier A \<Longrightarrow> !(!x) = x" sorry
lemma de_morgan1: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> !x \<sqinter> !y = !(x \<squnion> y)" sorry
lemma ba_meet_def: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqinter> y = !(!x \<squnion> !y)" sorry
lemma de_morgan2: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> !x \<squnion> !y = !(x \<sqinter> y)" sorry
lemma compl_anti: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<sqsubseteq> y \<longleftrightarrow> !y \<sqsubseteq> !x" sorry
lemma ba_join_def: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x \<squnion> y = !(!x \<sqinter> !y)" sorry
lemma ba_3: "\<lbrakk>x \<in> carrier A; y \<in> carrier A\<rbrakk> \<Longrightarrow> x = (x \<sqinter> y) \<squnion> (x \<sqinter> !y)" sorry
*)
end
(* +------------------------------------------------------------------------+ *)
subsection {* Complete join semilattices *}
(* +------------------------------------------------------------------------+ *)
locale complete_join_semilattice = order +
assumes lub_ex: "\<lbrakk>X \<subseteq> carrier A\<rbrakk> \<Longrightarrow> \<exists>x\<in>carrier A. is_lub x X"
sublocale complete_join_semilattice \<subseteq> join_semilattice
by default (metis bot_least insert_subset lub_ex)
context complete_join_semilattice
begin
lemma bot_ax: "\<exists>!b\<in>carrier A. \<forall>x\<in>carrier A. b \<sqsubseteq> x"
by (metis (no_types) order_antisym bot_least equals0D is_lub_def lub_ex)
definition bot :: "'a" ("\<bottom>") where "\<bottom> \<equiv> THE x. x\<in>carrier A \<and> (\<forall>y\<in>carrier A. x \<sqsubseteq> y)"
lemma bot_closed: "\<bottom> \<in> carrier A" by (smt bot_def the1I2 bot_ax)
lemma prop_bot: "\<forall>x\<in>carrier A. \<bottom> \<sqsubseteq> x"
by (simp only: bot_def, rule the1I2, smt bot_ax, metis)
lemma is_lub_lub [intro?]: "X \<subseteq> carrier A \<Longrightarrow> is_lub (\<Sigma> X) X"
by (metis lub_ex lub_is_lub)
lemma lub_ex_var: "X \<subseteq> carrier A \<Longrightarrow> \<exists>!x. is_lub x X"
by (metis is_lub_lub lub_is_lub)
lemma lub_ex_var2: "X \<subseteq> carrier A \<Longrightarrow> \<exists>x. is_lub x X"
by (metis lub_ex)
lemma lub_greatest [intro?]: "\<lbrakk>x \<in> carrier A; X \<subseteq> carrier A; \<forall>y\<in>X. y \<sqsubseteq> x\<rbrakk> \<Longrightarrow> \<Sigma> X \<sqsubseteq> x"
by (metis is_lub_def is_lub_lub)
lemma lub_least [intro?]: "\<lbrakk>X \<subseteq> carrier A; x \<in> X\<rbrakk> \<Longrightarrow> x \<sqsubseteq> \<Sigma> X"