-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPoset.thy
1610 lines (1369 loc) · 78.3 KB
/
Poset.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
section \<open> Poset.thy \<close>
theory Poset
imports Main Function
begin
(* Poset type *)
record 'a Poset =
el :: "'a set"
le_rel :: "('a \<times> 'a) set"
definition "Poset_le_undefined_arg_not_in_domain a a' \<equiv> undefined"
abbreviation le :: "'a Poset \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> bool)" where
"le P a a' \<equiv>
if a \<in> el P \<and> a' \<in> el P
then (a, a') \<in> le_rel P
else Poset_le_undefined_arg_not_in_domain a a'"
(*
abbreviation le_P :: "'a \<Rightarrow> 'a Poset \<Rightarrow> 'a \<Rightarrow> bool" ("_ \<sqsubseteq>\<langle>_\<rangle> _") where
"le_P a P a' \<equiv> (a, a') \<in> le_rel P"
*)
definition valid :: "'a Poset \<Rightarrow> bool" where
"valid P \<equiv>
let
welldefined = \<forall>x y. (x,y) \<in> le_rel P \<longrightarrow> x \<in> el P \<and> y \<in> el P;
reflexivity = \<forall>x. x \<in> el P \<longrightarrow> (x,x) \<in> le_rel P;
antisymmetry = \<forall>x y. x \<in> el P \<longrightarrow> y \<in> el P \<longrightarrow> (x,y) \<in> le_rel P \<longrightarrow> (y,x) \<in> le_rel P \<longrightarrow> x = y;
transitivity = \<forall>x y z. x \<in> el P \<longrightarrow> y \<in> el P \<longrightarrow> z \<in> el P \<longrightarrow> (x,y) \<in> le_rel P \<longrightarrow> (y,z) \<in> le_rel P\<longrightarrow> (x,z) \<in> le_rel P
in
welldefined \<and> reflexivity \<and> antisymmetry \<and> transitivity"
(* PosetMap type (monotone function *)
record ('a, 'b) PosetMap =
dom :: "'a Poset"
cod :: "'b Poset"
func ::"('a \<times>'b) set"
definition "Poset_app_undefined_arg_not_in_domain a \<equiv> undefined"
(* Map application *)
definition app :: "('a, 'b) PosetMap \<Rightarrow> 'a \<Rightarrow> 'b" (infixr "\<star>" 997) where
"app f a \<equiv>
if a \<in> el (dom f)
then (THE b. (a, b) \<in> func f)
else Poset_app_undefined_arg_not_in_domain a"
definition valid_map :: "('a, 'b) PosetMap \<Rightarrow> bool" where
"valid_map f \<equiv>
let
le_dom = le (dom f);
le_cod = le (cod f);
e_dom = el (dom f);
e_cod = el (cod f);
welldefined = valid (dom f) \<and> valid (cod f) \<and> (\<forall>a b. (a, b) \<in> func f \<longrightarrow> a \<in> e_dom \<and> b \<in> e_cod);
deterministic = \<forall>a b b'. (a, b) \<in> func f \<and> (a, b') \<in> func f \<longrightarrow> b = b';
total = \<forall>a. a \<in> e_dom \<longrightarrow> (\<exists>b. (a, b) \<in> func f);
monotone = \<forall>a a'. a \<in> e_dom \<and> a' \<in> e_dom \<and> le_dom a a' \<longrightarrow> le_cod (f \<star> a) (f \<star> a')
in welldefined \<and> deterministic \<and> total \<and> monotone"
(* Validity *)
lemma validI [intro]:
fixes P :: "'a Poset"
assumes welldefined : "(\<And>x y. (x,y) \<in> le_rel P \<Longrightarrow> x \<in> el P \<and> y \<in> el P)"
and reflexivity : "(\<And>x. x \<in> el P \<Longrightarrow> le P x x)"
and antisymmetry : "(\<And>x y. x \<in> el P \<Longrightarrow> y \<in> el P \<Longrightarrow> le P x y \<Longrightarrow> le P y x \<Longrightarrow> x = y)"
and transitivity : "(\<And>x y z. x \<in> el P \<Longrightarrow> y \<in> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> le P x y \<Longrightarrow> le P y z \<Longrightarrow> le P x z)"
shows "valid P"
by (smt (verit, best) antisymmetry reflexivity transitivity valid_def welldefined)
lemma valid_welldefined : "valid P \<Longrightarrow> (x,y) \<in> le_rel P \<Longrightarrow> x \<in> el P \<and> y \<in> el P"
by (smt (verit) valid_def)
lemma valid_reflexivity : "valid P \<Longrightarrow> x \<in> el P \<Longrightarrow> le P x x"
by (smt (verit) valid_def)
lemma valid_transitivity : "valid P \<Longrightarrow> x \<in> el P \<Longrightarrow> y \<in> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> le P x y \<Longrightarrow> le P y z \<Longrightarrow> le P x z"
by (smt (verit, ccfv_threshold) valid_def)
lemma valid_antisymmetry : "valid P \<Longrightarrow> x \<in> el P \<Longrightarrow> y \<in> el P\<Longrightarrow> le P x y \<Longrightarrow> le P y x \<Longrightarrow> x = y"
by (smt (verit, ccfv_threshold) valid_def)
lemma valid_mapI [intro] : "valid (dom f) \<Longrightarrow> valid (cod f) \<Longrightarrow> (\<And>a b. (a, b) \<in> func f \<Longrightarrow> a \<in> el (dom f) \<and> b \<in> el (cod f)) \<Longrightarrow>
(\<And>a b b'. (a, b) \<in> func f \<Longrightarrow> (a, b') \<in> func f \<Longrightarrow> b = b') \<Longrightarrow>
(\<And>a. a \<in> el (dom f) \<Longrightarrow> (\<exists>b. (a, b) \<in> func f)) \<Longrightarrow>
(\<And>a a'. a \<in> el (dom f) \<Longrightarrow> a' \<in> el (dom f) \<Longrightarrow> le (dom f) a a' \<Longrightarrow> le (cod f) (f \<star> a) (f \<star> a'))
\<Longrightarrow> valid_map f" unfolding valid_map_def
by auto
lemma valid_map_welldefined_dom : "valid_map f \<Longrightarrow> valid (dom f)"
apply (subst (asm) valid_map_def)
by (clarsimp simp: Let_unfold)
lemma valid_map_welldefined_cod : "valid_map f \<Longrightarrow> valid (cod f)"
apply (subst (asm) valid_map_def)
by (clarsimp simp: Let_unfold)
lemma valid_map_welldefined_func : "valid_map f \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> a \<in> el (dom f) \<and> b \<in> el (cod f)"
unfolding valid_map_def
by (simp add: Let_def)
lemma valid_map_welldefined : "valid_map f \<Longrightarrow> valid (dom f) \<and> valid (cod f) \<and> (\<forall>a b. (a, b) \<in> func f \<longrightarrow> a \<in>
el (dom f) \<and> b \<in> el (cod f))"
by (simp add: valid_map_welldefined_cod valid_map_welldefined_dom valid_map_welldefined_func)
lemma valid_map_dom: "valid_map f \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> a \<in> el (dom f)"
by (meson valid_map_welldefined)
lemma valid_map_cod: "valid_map f \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> b \<in> el (cod f)"
by (meson valid_map_welldefined)
lemma valid_map_deterministic : "valid_map f \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> (a, b') \<in> func f \<Longrightarrow> b = b'"
unfolding valid_map_def
by (simp add: Let_def)
lemma valid_map_total : "valid_map f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> \<exists>b. (a, b) \<in> func f"
unfolding valid_map_def
by (simp add: Let_def)
lemma valid_map_monotone : "valid_map f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> a' \<in> el (dom f) \<Longrightarrow> le (dom f) a a' \<Longrightarrow> le (cod f) (f \<star> a) (f \<star> a')"
unfolding valid_map_def
by metis
lemma valid_map_eqI: "cod f = cod g \<Longrightarrow> dom f = dom g \<Longrightarrow> func f = func g \<Longrightarrow> (f :: ('a, 'b) PosetMap) = g"
by simp
(* Map application *)
lemma fun_app : "valid_map f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> (a, f \<star> a) \<in> func f"
by (metis app_def the_equality valid_map_deterministic valid_map_total)
lemma fun_app2 : "valid_map f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> f \<star> a \<in> el (cod f)"
by (meson fun_app valid_map_welldefined)
lemma fun_app3 : "a \<in> el (dom f) \<Longrightarrow> f \<star> a = (THE b. (a, b) \<in> func f) "
by (simp add: app_def)
lemma fun_ext_raw : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom f = dom g \<Longrightarrow> cod f = cod g \<Longrightarrow> (\<And>a. a \<in> el (dom f) \<Longrightarrow> f \<star> a = g \<star> a) \<Longrightarrow> func f = func g"
by (metis Poset.fun_app pred_equals_eq2 valid_map_deterministic valid_map_welldefined_func)
lemma fun_ext : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom f = dom g \<Longrightarrow> cod f = cod g \<Longrightarrow> (\<And> a . a \<in> el (dom f) \<Longrightarrow> f \<star> a = g \<star> a) \<Longrightarrow> f = g"
by (meson Poset.fun_ext_raw valid_map_eqI)
lemma fun_app_iff : "valid_map f \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> f \<star> a = b"
by (meson fun_app valid_map_deterministic valid_map_welldefined)
(* Map composition *)
definition "Poset_compose_undefined_incomposable g f \<equiv> undefined"
definition compose :: "('b, 'c) PosetMap \<Rightarrow> ('a, 'b) PosetMap \<Rightarrow> ('a, 'c) PosetMap" (infixl "\<diamondop>" 55) where
"compose g f \<equiv>
if dom g = cod f
then \<lparr> dom = dom f, cod = cod g, func = relcomp (func f) (func g) \<rparr>
else Poset_compose_undefined_incomposable g f"
lemma compose_welldefined_cod : "valid_map g \<Longrightarrow> valid_map f \<Longrightarrow> dom g = cod f \<Longrightarrow> (a, b) \<in> func (g \<diamondop> f) \<Longrightarrow> b \<in> el (cod g)"
unfolding compose_def
using Poset.valid_map_welldefined by auto
lemma compose_welldefined_dom : "valid_map g \<Longrightarrow> valid_map f \<Longrightarrow> dom g = cod f \<Longrightarrow> (a, b) \<in> func (g \<diamondop> f) \<Longrightarrow> a \<in> el (dom f)"
unfolding compose_def
using Poset.valid_map_welldefined by auto
lemma compose_welldefined : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom g = cod f \<Longrightarrow> (a, b) \<in> func (g \<diamondop> f) \<Longrightarrow> a \<in> el (dom f) \<and> b \<in> el (cod g)"
by (metis Poset.valid_map_welldefined PosetMap.select_convs(3) compose_def relcomp.cases)
lemma compose_deterministic : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom g = cod f \<Longrightarrow> (a, b) \<in> func (g \<diamondop> f) \<Longrightarrow> (a, b') \<in> func (g \<diamondop> f) \<Longrightarrow> b = b'"
by (metis (no_types, opaque_lifting) Poset.valid_map_deterministic PosetMap.select_convs(3) compose_def relcomp.cases)
lemma compose_total : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom g = cod f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> \<exists>b. (a, b) \<in> func (g \<diamondop> f)"
unfolding compose_def
by (smt (z3) Poset.fun_app Poset.fun_app2 PosetMap.select_convs(3) relcomp.relcompI)
lemma dom_compose [simp] : "dom g = cod f \<Longrightarrow> dom (g \<diamondop> f) = dom f"
unfolding compose_def
by (simp add: Let_def)
lemma cod_compose [simp] : "dom g = cod f \<Longrightarrow> cod (g \<diamondop> f) = cod g"
unfolding compose_def
by (simp add: Let_def)
lemma compose_app_assoc: "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> dom g = cod f \<Longrightarrow> (g \<diamondop> f) \<star> a = g \<star> (f \<star> a)"
apply (clarsimp simp: app_def, safe)
apply (smt (z3) Poset.fun_app PosetMap.select_convs(3) compose_def compose_deterministic fun_app_iff relcomp.relcompI theI')
by (metis app_def fun_app2)
lemma compose_monotone :
fixes f :: "('a,'b) PosetMap" and g :: "('b,'c) PosetMap" and a a' :: "'a"
assumes f_valid : "valid_map f" and g_valid : "valid_map g"
and a_elem : "a \<in> el (dom f)" and a'_elem : "a' \<in> el (dom f)"
and le_aa' : "le (dom f) a a'"
and dom_cod : "dom g = cod f"
shows "le (cod g) ((g \<diamondop> f) \<star> a) ((g \<diamondop> f) \<star> a')"
by (metis (no_types, opaque_lifting) Poset.compose_app_assoc Poset.fun_app2 a'_elem a_elem dom_cod f_valid g_valid le_aa' valid_map_monotone)
lemma compose_valid : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> dom g = cod f \<Longrightarrow> valid_map (g \<diamondop> f)"
proof (intro valid_mapI, safe, goal_cases)
case 1
then show ?case
by (simp add: Poset.valid_map_welldefined_dom)
next
case 2
then show ?case
by (simp add: Poset.valid_map_welldefined_cod)
next
case (3 a b)
then show ?case
by (simp add: Poset.compose_welldefined_dom)
next
case (4 a b)
then show ?case
by (simp add: Poset.compose_welldefined_cod)
next
case (5 a b b')
then show ?case
by (meson Poset.compose_deterministic)
next
case (6 a)
then show ?case
by (simp add: Poset.compose_total)
next
case (7 a a')
then show ?case
by (simp add: compose_monotone)
qed
lemma compose_app [simp] : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> (a, b) \<in> func f \<Longrightarrow> dom g = cod f \<Longrightarrow>
(b, c) \<in> func g \<Longrightarrow> (g \<diamondop> f) \<star> a = c"
apply (rule fun_app_iff)
using compose_valid apply blast
by (simp add: compose_def relcomp.relcompI)
lemma compose_assoc : "valid_map f \<Longrightarrow> valid_map g \<Longrightarrow> valid_map h \<Longrightarrow> dom g = cod f \<Longrightarrow> dom h = cod g
\<Longrightarrow> (h \<diamondop> g) \<diamondop> f = h \<diamondop> (g \<diamondop> f)"
by (smt (verit) Poset.cod_compose Poset.compose_app_assoc Poset.compose_valid Poset.dom_compose Poset.fun_app2 Poset.fun_ext)
(* Proof techniques *)
lemma indirect_inequality_lower :
fixes P :: "'a Poset" and a b :: "'a"
assumes P_valid : "valid P"
and "a \<in> el P" and "b \<in> el P"
shows "le P a b = (\<forall> c \<in> el P . (le P b c \<longrightarrow> le P a c))"
by (smt (verit, best) P_valid assms(2) assms(3) valid_reflexivity valid_transitivity)
lemma indirect_inequality_higher :
fixes P :: "'a Poset" and a b :: "'a"
assumes P_valid : "valid P"
and "a \<in> el P" and "b \<in> el P"
shows "le P a b = (\<forall> c \<in> el P . (le P c a \<longrightarrow> le P c b))"
by (smt (verit, best) P_valid assms(2) assms(3) valid_reflexivity valid_transitivity)
lemma indirect_equality_lower :
fixes P :: "'a Poset" and a b :: "'a"
assumes P_valid : "valid P"
and "a \<in> el P" and "b \<in> el P"
shows "a = b = (\<forall> c \<in> el P . (le P b c = le P a c))"
by (smt (verit, del_insts) P_valid assms(2) assms(3) valid_antisymmetry valid_reflexivity)
lemma indirect_equality_higher :
fixes P :: "'a Poset" and a b :: "'a"
assumes P_valid : "valid P"
and "a \<in> el P" and "b \<in> el P"
shows "a = b = (\<forall> c \<in> el P . (le P c a = le P c b))"
by (smt (verit, del_insts) P_valid assms(2) assms(3) valid_antisymmetry valid_reflexivity)
(* Properties *)
definition is_surjective :: "('a, 'b) PosetMap \<Rightarrow> bool" where
"is_surjective f \<equiv> \<forall> b . b \<in> el (cod f) \<longrightarrow> (\<exists> a . a \<in> el (dom f) \<and> f \<star> a = b)"
definition is_injective :: "('a, 'b) PosetMap \<Rightarrow> bool" where
"is_injective f \<equiv> \<forall>a a' . a \<in> el (dom f) \<longrightarrow> a' \<in> el (dom f) \<longrightarrow> f \<star> a = f \<star> a' \<longrightarrow> a = a'"
definition is_bijective :: "('a, 'b) PosetMap \<Rightarrow> bool" where
"is_bijective f \<equiv> is_surjective f \<and> is_injective f"
lemma surjection_is_right_cancellative : "valid_map f \<Longrightarrow> is_surjective f \<Longrightarrow>
valid_map g \<Longrightarrow> valid_map h \<Longrightarrow> cod f = dom g \<Longrightarrow> cod f = dom h \<Longrightarrow> g \<diamondop> f = h \<diamondop> f \<Longrightarrow> g = h"
by (metis Poset.cod_compose Poset.compose_app_assoc Poset.fun_ext Poset.is_surjective_def)
lemma injection_is_left_cancellative : "valid_map f \<Longrightarrow> is_injective f \<Longrightarrow>
valid_map g \<Longrightarrow> valid_map h \<Longrightarrow> cod g = dom f \<Longrightarrow> cod h = dom f \<Longrightarrow> f \<diamondop> g = f \<diamondop> h \<Longrightarrow> g = h"
by (smt (verit, ccfv_threshold) Poset.compose_app_assoc Poset.dom_compose Poset.fun_app2 Poset.fun_ext Poset.is_injective_def)
(* Identity maps *)
definition ident :: "'a Poset \<Rightarrow> ('a, 'a) PosetMap" where
"ident P \<equiv> \<lparr> dom = P, cod = P, func = Id_on (el P) \<rparr>"
lemma ident_valid : "valid P \<Longrightarrow> valid_map (ident P)"
unfolding valid_map_def ident_def app_def
apply ( simp add: Let_unfold Id_on_def )
by blast
lemma ident_dom [simp] : "dom (ident P) = P"
by (simp add: ident_def)
lemma ident_cod [simp] : "cod (ident P) = P"
by (simp add: ident_def)
lemma ident_func [simp] : "func (ident P) = Id_on (el P)"
by (simp add: ident_def)
lemma ident_app [simp] :
fixes a :: "'a" and P :: "'a Poset"
assumes "valid P" and "a \<in> el P"
shows "ident P \<star> a = a"
by (metis Id_onI Poset.fun_app_iff Poset.ident_def Poset.ident_valid PosetMap.select_convs(3) assms(1) assms(2))
lemma compose_ident_left [simp] : "valid_map f \<Longrightarrow> ident (cod f) \<diamondop> f = f"
by (smt (verit, best) Poset.cod_compose Poset.compose_app_assoc Poset.compose_valid Poset.dom_compose Poset.fun_app2 Poset.fun_ext Poset.ident_app Poset.ident_cod Poset.ident_dom Poset.ident_valid valid_map_welldefined_cod)
lemma compose_ident_right [simp] : "valid_map f \<Longrightarrow> f \<diamondop> ident (dom f) = f"
by (smt (verit, ccfv_SIG) Poset.cod_compose Poset.compose_app_assoc Poset.compose_valid Poset.dom_compose Poset.fun_ext Poset.ident_app Poset.ident_cod Poset.ident_dom Poset.ident_valid valid_map_welldefined_dom)
(* Constant maps *)
definition "PosetMap_const_undefined_arg_not_in_codomain b \<equiv> undefined"
definition const :: "'a Poset \<Rightarrow> 'b Poset \<Rightarrow> 'b \<Rightarrow> ('a, 'b) PosetMap" where
"const P Q q \<equiv>
if q \<in> el Q
then \<lparr> dom = P, cod = Q, func = { (p, q) | p . p \<in> el P } \<rparr>
else PosetMap_const_undefined_arg_not_in_codomain q"
lemma const_dom [simp] : "q \<in> el Q \<Longrightarrow> dom (const P Q q) = P"
by (simp add: const_def)
lemma const_cod [simp] : "q \<in> el Q \<Longrightarrow> cod (const P Q q) = Q"
by (simp add: const_def)
lemma const_app [simp] : "valid P \<Longrightarrow> valid Q \<Longrightarrow> p \<in> el P \<Longrightarrow> q \<in> el Q \<Longrightarrow> ((const P Q q) \<star> p) = q"
unfolding const_def app_def
by auto
lemma const_valid : "valid P \<Longrightarrow> valid Q \<Longrightarrow> q \<in> el Q \<Longrightarrow> valid_map (const P Q q)"
proof (intro valid_mapI,goal_cases)
case 1
then show ?case
by simp
next
case 2
then show ?case
by simp
next
case (3 a b)
then show ?case
by (simp add: Poset.const_def)
next
case (4 a b b')
then show ?case
by (simp add: Poset.const_def)
next
case (5 a)
then show ?case by (simp add: const_def)
next
case (6 a a')
then show ?case
by (simp add: valid_reflexivity)
qed
(* Cartesian product of posets *)
definition product :: "'a Poset \<Rightarrow> 'b Poset \<Rightarrow> ('a \<times> 'b) Poset" (infixl "\<times>\<times>" 55) where
"product P Q \<equiv> \<lparr> el = el P \<times> el Q, le_rel =
{(x, y). fst x \<in> el P \<and> snd x \<in> el Q \<and> fst y \<in> el P \<and> snd y \<in> el Q \<and> (fst x, fst y) \<in> le_rel P \<and> (snd x, snd y) \<in> le_rel Q} \<rparr>"
lemma product_valid : "valid P \<Longrightarrow> valid Q \<Longrightarrow> valid (P \<times>\<times> Q)"
unfolding valid_def product_def
by (smt (verit) Poset.Poset.select_convs(1) Poset.Poset.select_convs(2) Product_Type.Collect_case_prodD SigmaE SigmaI case_prodI fst_conv mem_Collect_eq prod.collapse snd_conv)
lemma product_el_1 : "(a,b) \<in> el (P \<times>\<times> Q) \<Longrightarrow> a \<in> el P"
by (simp add: Poset.product_def)
lemma product_el_2 : "(a,b) \<in> el (P \<times>\<times> Q) \<Longrightarrow> b \<in> el Q"
by (simp add: Poset.product_def)
lemma product_le_1 : "valid P \<Longrightarrow> valid Q \<Longrightarrow> ((a, b),(a', b')) \<in> le_rel (P \<times>\<times> Q) \<Longrightarrow> (a,a') \<in> le_rel P"
by (simp add: Poset.product_def)
lemma product_le_2 : "valid P \<Longrightarrow> valid Q \<Longrightarrow> ((a, b),(a', b')) \<in> le_rel (P \<times>\<times> Q) \<Longrightarrow> (b,b') \<in> le_rel Q"
by (simp add: Poset.product_def)
(* Discrete poset *)
definition discrete :: "'a Poset" where
"discrete \<equiv> \<lparr> el = UNIV , le_rel = {x. fst x = snd x} \<rparr>"
lemma discrete_valid : "valid discrete"
by (simp add: discrete_def valid_def)
(* Infima and suprema *)
definition is_inf :: "'a Poset \<Rightarrow> 'a set \<Rightarrow> 'a \<Rightarrow> bool" where
"is_inf P U i \<equiv> U \<subseteq> el P \<and> i \<in> el P \<and> (\<forall>u\<in>U. le P i u) \<and> (\<forall>z \<in> el P. (\<forall>u\<in>U. le P z u) \<longrightarrow> le P z i)"
definition is_sup :: "'a Poset \<Rightarrow> 'a set \<Rightarrow> 'a \<Rightarrow> bool" where
"is_sup P U s \<equiv> U \<subseteq> el P \<and> s \<in> el P \<and> (\<forall>u\<in>U. le P u s) \<and> (\<forall>z \<in> el P. (\<forall>u\<in>U. le P u z) \<longrightarrow> le P s z)"
abbreviation is_bot :: "'a Poset \<Rightarrow> 'a \<Rightarrow> bool" where
"is_bot P b \<equiv> b \<in> el P \<and> (\<forall>p \<in> el P. le P b p)"
abbreviation is_top :: "'a Poset \<Rightarrow> 'a \<Rightarrow> bool" where
"is_top P t \<equiv> t \<in> el P \<and> (\<forall>p \<in> el P. le P p t)"
definition inf :: "'a Poset \<Rightarrow> 'a set \<Rightarrow> 'a " where
"inf P U \<equiv> SOME i. is_inf P U i"
definition sup :: "'a Poset \<Rightarrow> 'a set \<Rightarrow> 'a " where
"sup P U \<equiv> SOME s. is_sup P U s"
definition meet :: "'a Poset \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a " where
"meet P a b \<equiv> inf P {a,b}"
definition join :: "'a Poset \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a " where
"join P a b \<equiv> sup P {a,b}"
definition is_complete :: "'a Poset \<Rightarrow> bool" where
"is_complete P \<equiv> valid P \<and> (\<forall>U. U \<subseteq> el P \<longrightarrow> (\<exists> i. is_inf P U i) \<and> inf P U \<in> el P)"
definition is_cocomplete :: "'a Poset \<Rightarrow> bool" where
"is_cocomplete P \<equiv> valid P \<and> (\<forall>U. U \<subseteq> el P \<longrightarrow> (\<exists> i. is_sup P U i) \<and> sup P U \<in> el P)"
lemma inf_unique : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> i \<in> el P\<Longrightarrow> i' \<in> el P \<Longrightarrow> is_inf P U i \<Longrightarrow> is_inf P U i' \<Longrightarrow> i = i'"
unfolding is_inf_def
by (metis valid_antisymmetry)
lemma sup_unique : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> s \<in> el P\<Longrightarrow> s' \<in> el P \<Longrightarrow> is_sup P U s \<Longrightarrow> is_sup P U s' \<Longrightarrow> s = s'"
unfolding is_sup_def
by (metis valid_antisymmetry)
lemma is_inf_is_glb : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> i \<in> el P \<Longrightarrow> is_inf P U i
\<Longrightarrow> \<forall>u\<in>U. le P z u \<Longrightarrow> le P z i"
by (simp add: is_inf_def)
lemma is_sup_is_lub : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> s \<in> el P \<Longrightarrow> is_sup P U s
\<Longrightarrow> \<forall>u\<in>U. le P u z \<Longrightarrow> le P s z"
by (simp add: is_sup_def)
lemma is_inf_smaller : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> i \<in> el P \<Longrightarrow> is_inf P U i \<Longrightarrow> \<forall> u \<in> U. le P i u"
unfolding is_inf_def
by blast
lemma is_sup_greater : "valid P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> s \<in> el P \<Longrightarrow> is_sup P U s \<Longrightarrow> \<forall> u \<in> U. le P u s"
unfolding is_sup_def
by blast
lemma inf_is_glb : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> \<forall>u\<in>U. le P z u \<Longrightarrow> le P z (inf P U)"
by (simp add: inf_def is_inf_is_glb is_complete_def someI_ex)
lemma sup_is_lub : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> z \<in> el P \<Longrightarrow> \<forall>u\<in>U. le P u z \<Longrightarrow> le P (sup P U) z"
by (simp add: sup_def is_sup_is_lub is_cocomplete_def someI_ex)
lemma complete_inf_exists : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> \<exists>i \<in> el P. is_inf P U i"
by (smt (verit, best) is_complete_def is_inf_def)
lemma cocomplete_sup_exists : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> \<exists>s \<in> el P. is_sup P U s"
by (smt (verit, del_insts) is_cocomplete_def is_sup_def)
lemma sup_greater : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> a \<in> U \<Longrightarrow> \<forall> u \<in> U. le P a (sup P U)"
by (metis is_cocomplete_def is_sup_greater someI_ex sup_def)
lemma inf_smaller : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> a \<in> U \<Longrightarrow> \<forall> u \<in> U. le P (inf P U) a"
by (metis inf_def is_complete_def is_inf_smaller someI_ex)
lemma complete_meet_is_inf : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> is_inf P {a, b} (meet P a b)"
by (simp add: inf_def is_complete_def meet_def someI_ex)
lemma cocomplete_join_is_sup: "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> is_sup P {a, b} (join P a b)"
by (simp add: is_cocomplete_def join_def someI_ex sup_def)
lemma meet_smaller1 : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P (meet P a b) a"
by (smt (verit) complete_meet_is_inf insertCI is_inf_def)
lemma meet_smaller2 : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P (meet P a b) b"
by (smt (verit, ccfv_threshold) complete_meet_is_inf insertCI is_inf_def)
lemma meet_smaller : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P (meet P a b) a \<and> le P (meet P a b) b"
by (simp add: meet_smaller1 meet_smaller2)
lemma join_greater1 : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P a (join P a b)"
by (smt (verit) cocomplete_join_is_sup insertCI is_sup_def)
lemma join_greater2 : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P b (join P a b)"
by (smt (verit, ccfv_threshold) cocomplete_join_is_sup insertCI is_sup_def)
lemma join_greater : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P a (join P a b) \<and> le P b (join P a b)"
by (simp add: join_greater1 join_greater2)
lemma meet_el : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> meet P a b \<in> el P"
by (simp add: is_complete_def meet_def)
lemma join_el : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> join P a b \<in> el P"
by (simp add: is_cocomplete_def join_def)
lemma sup_el : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> sup P U \<in> el P"
using is_cocomplete_def by blast
lemma inf_el : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> inf P U \<in> el P" using inf_def
using is_complete_def by blast
lemma meet_property : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> c \<in> el P \<Longrightarrow> le P c a \<Longrightarrow> le P c b \<Longrightarrow> le P c (meet P a b)"
using complete_meet_is_inf is_inf_def
by (smt (verit, ccfv_threshold) insert_iff meet_el singleton_iff)
lemma join_property : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> c \<in> el P \<Longrightarrow> le P a c \<Longrightarrow> le P b c \<Longrightarrow> le P (join P a b) c"
using cocomplete_join_is_sup is_sup_def
by (smt (verit, ccfv_threshold) insert_iff singleton_iff)
lemma meet_mono : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> a' \<in> el P \<Longrightarrow> b' \<in> el P \<Longrightarrow> le P a a' \<Longrightarrow> le P b b'
\<Longrightarrow> le P (meet P a b) (meet P a b')"
by (smt (verit, ccfv_threshold) is_complete_def meet_el meet_property meet_smaller1 meet_smaller2 valid_def)
lemma join_mono : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> a' \<in> el P \<Longrightarrow> b' \<in> el P \<Longrightarrow> le P a a' \<Longrightarrow> le P b b'
\<Longrightarrow> le P (join P a b) (join P a b')"
by (smt (verit, best) is_cocomplete_def join_el join_greater1 join_greater2 join_property valid_transitivity)
lemma meet_comm : "a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> meet P a b = meet P b a"
by (simp add: insert_commute meet_def)
lemma join_comm : "a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> join P a b = join P b a"
by (simp add: insert_commute join_def)
lemma meet_idem : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> meet P a a = a"
using is_complete_def meet_el meet_property meet_smaller1 valid_antisymmetry valid_reflexivity by fastforce
lemma join_idem : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> join P a a = a"
using is_cocomplete_def join_el join_greater1 join_property valid_antisymmetry valid_reflexivity by fastforce
lemma inf_is_inf : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> is_inf P U (inf P U)"
by (metis complete_inf_exists inf_def someI_ex)
lemma sup_is_sup : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> is_sup P U (sup P U)"
by (metis cocomplete_sup_exists sup_def someI_ex)
lemma inf_antimono : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> V \<subseteq> el P \<Longrightarrow> U \<subseteq> V \<Longrightarrow> le P (inf P V) (inf P U)"
by (smt (verit) inf_el inf_is_glb inf_smaller subsetD)
lemma sup_mono : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> V \<subseteq> el P \<Longrightarrow> U \<subseteq> V \<Longrightarrow> le P (sup P U) (sup P V)"
by (smt (verit, del_insts) in_mono sup_el sup_greater sup_is_lub)
lemma sup_singleton : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> sup P {a} = a"
by (smt (verit) insert_absorb2 is_cocomplete_def join_def join_el join_greater1 join_property valid_antisymmetry valid_reflexivity)
lemma inf_singleton : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> inf P {a} = a"
using insert_absorb2 is_complete_def inf_def inf_el meet_smaller1 meet_property inf_smaller is_inf_is_glb valid_antisymmetry valid_reflexivity
by (smt (verit, del_insts) meet_def meet_el)
lemma sup_el_le : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> a \<in> el P \<Longrightarrow> \<exists> u \<in> U . le P a u \<Longrightarrow> le P a (sup P U)"
by (smt (verit, ccfv_threshold) in_mono is_cocomplete_def sup_greater valid_transitivity)
lemma inf_el_le : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> a \<in> el P \<Longrightarrow> \<exists> u \<in> U . le P u a \<Longrightarrow> le P (inf P U) a"
by (smt (verit, ccfv_SIG) inf_smaller is_complete_def subsetD valid_def)
lemma sup_mono_pointwise : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> V \<subseteq> el P \<Longrightarrow> (\<forall> u \<in> U. \<exists> v \<in> V. le P u v) \<Longrightarrow> le P (sup P U) (sup P V)"
by (simp add: is_cocomplete_def subsetD sup_el_le sup_is_lub)
lemma inf_mono_pointwise : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> V \<subseteq> el P \<Longrightarrow> (\<forall> v \<in> V. \<exists> u \<in> U. le P u v) \<Longrightarrow> le P (inf P U) (inf P V)"
by (simp add: inf_el_le inf_is_glb is_complete_def subsetD)
lemma join_le : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P a b \<Longrightarrow> join P a b = b"
by (smt (verit, ccfv_threshold) is_cocomplete_def join_el join_greater join_property valid_def)
lemma inf_le : "is_complete P \<Longrightarrow> a \<in> el P \<Longrightarrow> b \<in> el P \<Longrightarrow> le P a b \<Longrightarrow> meet P a b = a"
by (smt (verit, del_insts) is_complete_def meet_el meet_idem meet_mono meet_smaller1 valid_antisymmetry)
lemma inf_as_sup : "is_complete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> sup P U = inf P {a \<in> el P . (\<forall> u \<in> U . le P u a)}"
proof -
assume "is_complete P "
fix U
assume "U \<subseteq> el P"
define "s" where "s = inf P {a \<in> el P . (\<forall> u \<in> U . le P u a)}"
have "is_sup P U s"
proof (simp add: is_sup_def, safe, goal_cases)
case (1 x)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case 2
then show ?case
by (simp add: \<open>is_complete P\<close> inf_el s_def)
next
case (3 u)
then show ?case
by (simp add: \<open>is_complete P\<close> inf_is_glb s_def)
next
case (4 u)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case (5 u)
then show ?case
by (simp add: \<open>is_complete P\<close> inf_el s_def)
next
case (6 z)
then show ?case
by (smt (verit) \<open>is_complete P\<close> inf_smaller is_complete_def mem_Collect_eq s_def subset_eq)
next
case (7 z)
then show ?case
by (simp add: \<open>is_complete P\<close> inf_el s_def)
qed
moreover have "sup P U = s"
by (smt (verit) Poset.sup_unique \<open>is_complete P\<close> calculation is_complete_def is_sup_def someI_ex sup_def)
thus "Poset.sup P U = Poset.inf P {a \<in> el P. \<forall>u\<in>U. le P u a}"
using s_def by blast
qed
lemma sup_as_inf : "is_cocomplete P \<Longrightarrow> U \<subseteq> el P \<Longrightarrow> inf P U = sup P {a \<in> el P . (\<forall> u \<in> U . le P a u)}"
proof -
assume "is_cocomplete P "
fix U
assume "U \<subseteq> el P"
define "i" where "i = sup P {a \<in> el P . (\<forall> u \<in> U . le P a u)}"
have "is_inf P U i"
proof (simp add: is_inf_def, safe, goal_cases)
case (1 x)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case 2
then show ?case
by (simp add: \<open>is_cocomplete P\<close> sup_el i_def)
next
case (3 u)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> sup_is_lub i_def)
next
case (4 u)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> i_def sup_el)
next
case (5 u)
then show ?case
using \<open>U \<subseteq> el P\<close> by auto
next
case (6 z)
then show ?case
by (smt (verit) \<open>is_cocomplete P\<close> sup_greater is_cocomplete_def mem_Collect_eq i_def subset_eq)
next
case (7 z)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> sup_el i_def)
qed
moreover have "inf P U = i"
by (smt (verit) Poset.inf_unique \<open>is_cocomplete P\<close> calculation is_cocomplete_def is_inf_def someI_ex inf_def)
thus "inf P U = sup P {a \<in> el P. \<forall>u\<in>U. le P a u}"
using i_def by blast
qed
lemma complete_equiv_cocomplete : "is_complete P = is_cocomplete P"
proof (safe, goal_cases)
case 1
then show ?case
proof (simp add: is_cocomplete_def)
assume "is_complete P"
show "valid P \<and> (\<forall>U\<subseteq>el P. (\<exists>i. is_sup P U i) \<and> Poset.sup P U \<in> el P) "
proof (rule conjI, goal_cases)
case 1
then show ?case
using \<open>is_complete P\<close> is_complete_def by blast
next
case 2
then show ?case
proof (rule allI, rule impI)
fix U
assume "U \<subseteq> el P"
define "s" where "s = inf P {a \<in> el P . (\<forall> u \<in> U . le P u a)}"
have "is_sup P U s"
proof (simp add: is_sup_def, safe, goal_cases)
case (1 x)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case 2
then show ?case
by (simp add: "1" inf_el s_def)
next
case (3 u)
then show ?case
by (simp add: "1" inf_is_glb s_def)
next
case (4 u)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case (5 u)
then show ?case
by (simp add: "1" inf_el s_def)
next
case (6 z)
then show ?case
by (smt (verit) "1" inf_smaller is_complete_def mem_Collect_eq s_def subset_eq)
next
case (7 z)
then show ?case
by (simp add: "1" inf_el s_def)
qed
then show "(\<exists>i. is_sup P U i) \<and> Poset.sup P U \<in> el P"
by (smt (verit, best) is_sup_def someI_ex sup_def)
qed
qed
qed
next
case 2
then show ?case
proof (simp add: is_complete_def)
assume "is_cocomplete P"
show "valid P \<and> (\<forall>U\<subseteq>el P. (\<exists>i. is_inf P U i) \<and> Poset.inf P U \<in> el P)"
proof (rule conjI, goal_cases)
case 1
then show ?case
using \<open>is_cocomplete P\<close> is_cocomplete_def by blast
next
case 2
then show ?case
proof (rule allI, rule impI)
fix U
assume "U \<subseteq> el P"
define "i" where "i = sup P {a \<in> el P . (\<forall> u \<in> U . le P a u)}"
have "is_inf P U i"
proof (simp add: is_inf_def, safe, goal_cases)
case (1 x)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case 2
then show ?case
by (simp add: \<open>is_cocomplete P\<close> i_def sup_el)
next
case (3 u)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> i_def sup_is_lub)
next
case (4 u)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> i_def sup_el)
next
case (5 u)
then show ?case
using \<open>U \<subseteq> el P\<close> by blast
next
case (6 z)
then show ?case
by (smt (verit, ccfv_SIG) \<open>is_cocomplete P\<close> i_def mem_Collect_eq subset_iff sup_greater)
next
case (7 z)
then show ?case
by (simp add: \<open>is_cocomplete P\<close> i_def sup_el)
qed
then show "(\<exists>i. is_inf P U i) \<and> Poset.inf P U \<in> el P"
by (smt (verit, best) inf_def is_inf_def someI_ex)
qed
qed
qed
qed
lemma sup_dist_join1 :
fixes P :: "'a Poset" and U :: "'a set" and a :: "'a"
assumes P_cocomplete : "is_cocomplete P" and U_els : "U \<subseteq> el P" and U_inhabited : "U \<noteq> {}" and a_el : "a \<in> el P"
shows "join P a (sup P U) = sup P {join P a u | u. u \<in> U}"
proof -
define "aU" where "aU = {join P a u | u. u \<in> U}"
then have "aU \<subseteq> el P" using aU_def
by (smt (verit) P_cocomplete U_els a_el join_el mem_Collect_eq subset_eq)
moreover have "join P a (sup P U) \<in> el P"
by (simp add: P_cocomplete U_els a_el join_el sup_el)
moreover have "sup P aU \<in> el P"
by (smt (verit, ccfv_threshold) P_cocomplete U_els a_el in_mono join_el mem_Collect_eq subsetI sup_el aU_def)
moreover have left: "le P (join P a (sup P U)) (sup P aU)"
proof -
have "\<exists> u . u \<in> U \<and> join P a u \<in> aU \<and> le P a (join P a u)"
using P_cocomplete U_els U_inhabited a_el join_greater1 aU_def by fastforce
moreover have "le P a (sup P aU)"
using P_cocomplete U_els a_el calculation join_el mem_Collect_eq subset_iff sup_el_le aU_def
by (smt (verit, ccfv_threshold))
moreover have "\<forall>u\<in>U. \<exists>v\<in>aU. le P u v" using aU_def
by (smt (verit) P_cocomplete U_els a_el join_greater mem_Collect_eq subsetD)
moreover have "le P (sup P U) (sup P aU)" using sup_mono_pointwise [where ?P=P and ?U=U and ?V=aU]
using P_cocomplete U_els \<open>aU \<subseteq> el P\<close> calculation(3) by fastforce
ultimately show ?thesis
by (simp add: P_cocomplete U_els \<open>Poset.sup P aU \<in> el P\<close> a_el join_property sup_el)
qed
moreover have right: "le P (sup P aU) (join P a (sup P U))"
proof -
have "\<forall>v \<in> aU. le P v (join P a (sup P U))" using aU_def
by (smt (verit, ccfv_threshold) P_cocomplete U_els \<open>aU \<subseteq> el P\<close> a_el in_mono join_greater1 join_mono mem_Collect_eq sup_el sup_greater)
thus ?thesis
by (simp add: P_cocomplete \<open>aU \<subseteq> el P\<close> \<open>join P a (Poset.sup P U) \<in> el P\<close> sup_is_lub)
qed
ultimately show ?thesis using aU_def P_cocomplete is_cocomplete_def valid_antisymmetry
by fastforce
qed
lemma sup_dist_join2 :
fixes P :: "'a Poset" and U :: "'a set" and a :: "'a"
assumes P_cocomplete : "is_cocomplete P" and U_els : "U \<subseteq> el P" and U_inhabited : "U \<noteq> {}" and a_el : "a \<in> el P"
shows "join P (sup P U) a = sup P {join P u a | u. u \<in> U}"
proof -
have "join P (sup P U) a = join P a (sup P U)"
by (simp add: P_cocomplete U_els a_el join_comm sup_el)
moreover have "sup P {join P u a | u. u \<in> U} = sup P {join P a u | u. u \<in> U}"
by (metis U_els a_el in_mono join_comm)
ultimately show ?thesis
by (simp add: P_cocomplete U_els U_inhabited a_el sup_dist_join1)
qed
(* Constants *)
definition top :: "'a Poset \<Rightarrow> 'a" where
"top P = sup P (el P) "
definition bot :: "'a Poset \<Rightarrow> 'a" where
"bot P = sup P {} "
lemma top_max : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> le P a (top P)"
by (simp add: sup_greater top_def)
lemma bot_min : "is_cocomplete P \<Longrightarrow> a \<in> el P \<Longrightarrow> le P (bot P) a"
by (simp add: bot_def sup_is_lub)
lemma top_as_inf : "is_complete P \<Longrightarrow> top P = inf P {}"
by (smt (verit) Poset.inf_unique complete_equiv_cocomplete dual_order.refl empty_iff empty_subsetI inf_def is_complete_def is_inf_def someI_ex sup_el sup_greater top_def)
lemma bot_as_inf : "is_complete P \<Longrightarrow> bot P = inf P (el P)"
by (smt (verit) Poset.sup_unique bot.extremum bot_def dual_order.refl empty_iff inf_smaller is_complete_def is_sup_def someI_ex sup_def)
(* Directed subsets *)
definition is_directed :: "'a Poset \<Rightarrow> 'a set \<Rightarrow> bool" where
"is_directed P U \<equiv> U \<subseteq> el P \<and> U \<noteq> {} \<and> (\<forall> a b . a \<in> U \<longrightarrow> b \<in> U \<longrightarrow> join P a b \<in> U)"
definition is_continuous :: "('a,'b) PosetMap \<Rightarrow> bool" where
"is_continuous f \<equiv> (\<forall> U . is_directed (dom f) U \<longrightarrow> f \<star> (sup (dom f) U) = sup (cod f) {f \<star> a | a . a \<in> U})"
(* Fixed points. C.f. https://isabelle.in.tum.de/library/HOL/HOL/Inductive.html *)
(* Least fixed point *)
definition lfp :: "('a , 'a) PosetMap \<Rightarrow> 'a" where
"lfp f \<equiv> inf (cod f) {a \<in> el (dom f) . le (cod f) (f \<star> a) a}"
lemma lfp_is_el : "is_complete P \<Longrightarrow> valid_map f \<Longrightarrow> dom f = P \<Longrightarrow> cod f = P \<Longrightarrow> lfp f \<in> el P"
by (simp add: Poset.lfp_def inf_el)
lemma lfp_lowerbound :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap" and a :: "'a"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and "a \<in> el P" and "le P (f \<star> a) a"
shows "le P (lfp f) a"
using Poset.lfp_def assms inf_is_inf is_inf_def
by (smt (verit, del_insts) mem_Collect_eq subset_iff)
lemma lfp_greatest :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap" and a :: "'a"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and "a \<in> el P" and "le P (f \<star> a) a"
shows "(\<And>u . u \<in> el P \<and> le P (f \<star> u) u \<Longrightarrow> le P a u) \<Longrightarrow> le P a (lfp f)"
using assms lfp_def [where ?f=f] inf_is_glb [where ?P=P]
by (metis (no_types, lifting) mem_Collect_eq subsetI)
lemma lfp_is_fp :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
shows "f \<star> (lfp f) = lfp f"
proof -
define "H" where "H = {x \<in> el (dom f) . le (cod f) (f \<star> x) x}"
define "a" where "a = inf (cod f) H"
have "lfp f = a"
using H_def Poset.lfp_def a_def by blast
have "a \<in> el P \<and> f \<star> a \<in> el P"
by (metis P_complete Poset.fun_app2 \<open>Poset.lfp f = a\<close> f_endo f_valid lfp_is_el)
moreover have "le P (f \<star> a) a"
by (smt (verit) H_def P_complete Poset.fun_app2 a_def calculation f_endo f_valid inf_is_glb inf_smaller is_complete_def mem_Collect_eq subset_eq valid_map_monotone valid_transitivity)
moreover have "le P a (f \<star> a)"
proof -
have "le P (f \<star> (f \<star> a)) (f \<star> a)"
by (metis calculation(1) calculation(2) f_endo f_valid valid_map_monotone)
moreover have "f \<star> a \<in> H"
by (simp add: H_def \<open>a \<in> el P \<and> f \<star> a \<in> el P\<close> calculation f_endo)
ultimately show ?thesis
by (smt (verit, ccfv_SIG) H_def P_complete a_def f_endo inf_is_inf is_inf_def mem_Collect_eq subset_eq)
qed
ultimately show ?thesis
by (metis P_complete \<open>Poset.lfp f = a\<close> is_complete_def valid_antisymmetry)
qed
lemma lfp_unfold :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
shows "f \<star> (lfp f) = lfp f"
using P_complete f_endo f_valid lfp_is_fp by blast
lemma lfp_const :
fixes P :: "'a Poset" and a :: "'a"
assumes P_complete : "is_complete P"
and "a \<in> el P"
shows "lfp (const P P a) = a"
by (metis P_complete Poset.const_app Poset.const_cod Poset.const_dom Poset.const_valid Poset.lfp_unfold assms(2) is_complete_def lfp_is_el)
lemma lfp_eqI :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap" and a :: "'a"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and a_el : "a \<in> el P" and fp : "f \<star> a = a" and "\<And>b. b \<in> el P \<and> f \<star> b = b \<Longrightarrow> le P a b"
shows "lfp f = a"
by (metis P_complete Poset.lfp_lowerbound Poset.lfp_unfold a_el assms(6) f_endo f_valid fp is_complete_def lfp_is_el valid_antisymmetry)
lemma lfp_induct :
fixes P :: "'a Poset" and f :: "('a, 'a) PosetMap" and a :: "'a"
assumes P_complete : "is_complete P" and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and a_el : "a \<in> el P"
and ind : "le P (f \<star> (meet P (lfp f) a)) a"
shows "le P (lfp f) a"
by (smt (verit) P_complete Poset.fun_app2 Poset.lfp_lowerbound Poset.lfp_unfold a_el f_endo f_valid ind is_complete_def lfp_is_el meet_el meet_property meet_smaller valid_map_monotone valid_transitivity)
(* Greatest fixed point *)
definition gfp :: "('a , 'a) PosetMap \<Rightarrow> 'a" where
"gfp f \<equiv> sup (cod f) {a \<in> el (dom f) . le (cod f) a (f \<star> a)}"
lemma gfp_is_el : "is_cocomplete P \<Longrightarrow> valid_map f \<Longrightarrow> dom f = P \<Longrightarrow> cod f = P \<Longrightarrow> gfp f \<in> el P"
by (simp add: Poset.gfp_def sup_el)
(* Fusion *)
lemma right_subfusion :
fixes P :: "'a Poset" and f g h :: "('a, 'a) PosetMap"
assumes P_complete : "is_complete P"
and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and g_valid : "valid_map g" and g_endo : "dom g = P \<and> cod g = P"
and h_valid : "valid_map h" and h_endo : "dom h = P \<and> cod h = P"
and fg_le_gh : "\<And> a. a \<in> el P \<Longrightarrow> le P ((f \<diamondop> g) \<star> a) ((g \<diamondop> h) \<star> a)"
shows "le P (lfp f) (g \<star> (lfp h))"
by (metis (no_types, lifting) P_complete Poset.compose_app_assoc Poset.fun_app2 Poset.lfp_lowerbound Poset.lfp_unfold f_endo f_valid fg_le_gh g_endo g_valid h_endo h_valid lfp_is_el)
lemma left_subfusion :
fixes P :: "'a Poset" and f g h :: "('a, 'a) PosetMap"
assumes P_complete : "is_cocomplete P"
and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and g_valid : "valid_map g" and g_endo : "dom g = P \<and> cod g = P"
and h_valid : "valid_map h" and h_endo : "dom h = P \<and> cod h = P"
and fg_le_gh : "\<And> a. a \<in> el P \<Longrightarrow> le P ((f \<diamondop> g) \<star> a) ((h \<diamondop> f) \<star> a)"
and f_cont : "\<And> A . A \<subseteq> el P \<Longrightarrow> f \<star> (sup P A) = sup P {f \<star> a | a . a \<in> A}"
shows "le P (f \<star> (lfp g)) (lfp h)"
oops
lemma fusion :
fixes P :: "'a Poset" and f g h :: "('a, 'a) PosetMap"
assumes P_complete : "is_complete P"
and f_valid : "valid_map f" and f_endo : "dom f = P \<and> cod f = P"
and g_valid : "valid_map g" and g_endo : "dom g = P \<and> cod g = P"
and h_valid : "valid_map h" and h_endo : "dom h = P \<and> cod h = P"
and fg_eq_gh : "\<And> a. a \<in> el P \<Longrightarrow> ((f \<diamondop> g) \<star> a) = ((h \<diamondop> f) \<star> a)"
and f_cont : "\<And> A . A \<subseteq> el P \<Longrightarrow> f \<star> (sup P A) = sup P {f \<star> a | a . a \<in> A}"
shows "(f \<star> (lfp g)) = (lfp h)"
oops
(* Kleene *)
primrec iter :: "('a, 'a) PosetMap \<Rightarrow> nat \<Rightarrow> ('a, 'a) PosetMap" where
"iter f 0 = ident (dom f)"
| "iter f (Suc n) = f \<diamondop> (iter f n)"
lemma cod_iter : "valid_map f \<Longrightarrow> dom f = cod f \<Longrightarrow> cod (iter f n) = cod f"
apply (induct n)
apply simp
by fastforce
lemma dom_iter : "valid_map f \<Longrightarrow> dom f = cod f \<Longrightarrow> dom (iter f n) = dom f"
apply (induct n)
apply simp
by (simp add: cod_iter)
lemma iter_valid : "valid_map f \<Longrightarrow> dom f = cod f \<Longrightarrow> valid_map (iter f n)"
apply (induct n)
apply simp
using Poset.ident_valid valid_map_welldefined_cod apply blast
by (simp add: Poset.compose_valid cod_iter)
lemma iter_el : "valid_map f \<Longrightarrow> dom f = cod f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> iter f n \<star> a \<in> el (dom f)"
by (metis Poset.fun_app2 cod_iter dom_iter iter_valid)
lemma iter_app : "valid_map f \<Longrightarrow> dom f = cod f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> f \<star> (iter f n \<star> a) = iter f (n + 1) \<star> a"
by (simp add: Poset.compose_app_assoc cod_iter dom_iter iter_valid)
lemma iter_zero_app : "valid_map f \<Longrightarrow> a \<in> el (dom f) \<Longrightarrow> iter f 0 \<star> a = a"
by (simp add: Poset.valid_map_welldefined)
lemma iter_le_suc_iter :