-
Notifications
You must be signed in to change notification settings - Fork 307
/
SymmDiff.lean
870 lines (660 loc) · 29.6 KB
/
SymmDiff.lean
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
/-
Copyright (c) 2021 Bryan Gin-ge Chen. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Adam Topaz, Bryan Gin-ge Chen, Yaël Dillies
-/
import Mathlib.Order.BooleanAlgebra
import Mathlib.Logic.Equiv.Basic
#align_import order.symm_diff from "leanprover-community/mathlib"@"6eb334bd8f3433d5b08ba156b8ec3e6af47e1904"
/-!
# Symmetric difference and bi-implication
This file defines the symmetric difference and bi-implication operators in (co-)Heyting algebras.
## Examples
Some examples are
* The symmetric difference of two sets is the set of elements that are in either but not both.
* The symmetric difference on propositions is `Xor'`.
* The symmetric difference on `Bool` is `Bool.xor`.
* The equivalence of propositions. Two propositions are equivalent if they imply each other.
* The symmetric difference translates to addition when considering a Boolean algebra as a Boolean
ring.
## Main declarations
* `symmDiff`: The symmetric difference operator, defined as `(a \ b) ⊔ (b \ a)`
* `bihimp`: The bi-implication operator, defined as `(b ⇨ a) ⊓ (a ⇨ b)`
In generalized Boolean algebras, the symmetric difference operator is:
* `symmDiff_comm`: commutative, and
* `symmDiff_assoc`: associative.
## Notations
* `a ∆ b`: `symmDiff a b`
* `a ⇔ b`: `bihimp a b`
## References
The proof of associativity follows the note "Associativity of the Symmetric Difference of Sets: A
Proof from the Book" by John McCuan:
* <https://people.math.gatech.edu/~mccuan/courses/4317/symmetricdifference.pdf>
## Tags
boolean ring, generalized boolean algebra, boolean algebra, symmetric difference, bi-implication,
Heyting
-/
open Function OrderDual
variable {ι α β : Type*} {π : ι → Type*}
/-- The symmetric difference operator on a type with `⊔` and `\` is `(A \ B) ⊔ (B \ A)`. -/
def symmDiff [Sup α] [SDiff α] (a b : α) : α :=
a \ b ⊔ b \ a
#align symm_diff symmDiff
/-- The Heyting bi-implication is `(b ⇨ a) ⊓ (a ⇨ b)`. This generalizes equivalence of
propositions. -/
def bihimp [Inf α] [HImp α] (a b : α) : α :=
(b ⇨ a) ⊓ (a ⇨ b)
#align bihimp bihimp
/-- Notation for symmDiff -/
scoped[symmDiff] infixl:100 " ∆ " => symmDiff
/-- Notation for bihimp -/
scoped[symmDiff] infixl:100 " ⇔ " => bihimp
open scoped symmDiff
theorem symmDiff_def [Sup α] [SDiff α] (a b : α) : a ∆ b = a \ b ⊔ b \ a :=
rfl
#align symm_diff_def symmDiff_def
theorem bihimp_def [Inf α] [HImp α] (a b : α) : a ⇔ b = (b ⇨ a) ⊓ (a ⇨ b) :=
rfl
#align bihimp_def bihimp_def
theorem symmDiff_eq_Xor' (p q : Prop) : p ∆ q = Xor' p q :=
rfl
#align symm_diff_eq_xor symmDiff_eq_Xor'
@[simp]
theorem bihimp_iff_iff {p q : Prop} : p ⇔ q ↔ (p ↔ q) :=
(iff_iff_implies_and_implies _ _).symm.trans Iff.comm
#align bihimp_iff_iff bihimp_iff_iff
@[simp]
theorem Bool.symmDiff_eq_xor : ∀ p q : Bool, p ∆ q = xor p q := by decide
#align bool.symm_diff_eq_bxor Bool.symmDiff_eq_xor
section GeneralizedCoheytingAlgebra
variable [GeneralizedCoheytingAlgebra α] (a b c d : α)
@[simp]
theorem toDual_symmDiff : toDual (a ∆ b) = toDual a ⇔ toDual b :=
rfl
#align to_dual_symm_diff toDual_symmDiff
@[simp]
theorem ofDual_bihimp (a b : αᵒᵈ) : ofDual (a ⇔ b) = ofDual a ∆ ofDual b :=
rfl
#align of_dual_bihimp ofDual_bihimp
theorem symmDiff_comm : a ∆ b = b ∆ a := by simp only [symmDiff, sup_comm]
#align symm_diff_comm symmDiff_comm
instance symmDiff_isCommutative : Std.Commutative (α := α) (· ∆ ·) :=
⟨symmDiff_comm⟩
#align symm_diff_is_comm symmDiff_isCommutative
@[simp]
theorem symmDiff_self : a ∆ a = ⊥ := by rw [symmDiff, sup_idem, sdiff_self]
#align symm_diff_self symmDiff_self
@[simp]
theorem symmDiff_bot : a ∆ ⊥ = a := by rw [symmDiff, sdiff_bot, bot_sdiff, sup_bot_eq]
#align symm_diff_bot symmDiff_bot
@[simp]
theorem bot_symmDiff : ⊥ ∆ a = a := by rw [symmDiff_comm, symmDiff_bot]
#align bot_symm_diff bot_symmDiff
@[simp]
theorem symmDiff_eq_bot {a b : α} : a ∆ b = ⊥ ↔ a = b := by
simp_rw [symmDiff, sup_eq_bot_iff, sdiff_eq_bot_iff, le_antisymm_iff]
#align symm_diff_eq_bot symmDiff_eq_bot
theorem symmDiff_of_le {a b : α} (h : a ≤ b) : a ∆ b = b \ a := by
rw [symmDiff, sdiff_eq_bot_iff.2 h, bot_sup_eq]
#align symm_diff_of_le symmDiff_of_le
theorem symmDiff_of_ge {a b : α} (h : b ≤ a) : a ∆ b = a \ b := by
rw [symmDiff, sdiff_eq_bot_iff.2 h, sup_bot_eq]
#align symm_diff_of_ge symmDiff_of_ge
theorem symmDiff_le {a b c : α} (ha : a ≤ b ⊔ c) (hb : b ≤ a ⊔ c) : a ∆ b ≤ c :=
sup_le (sdiff_le_iff.2 ha) <| sdiff_le_iff.2 hb
#align symm_diff_le symmDiff_le
theorem symmDiff_le_iff {a b c : α} : a ∆ b ≤ c ↔ a ≤ b ⊔ c ∧ b ≤ a ⊔ c := by
simp_rw [symmDiff, sup_le_iff, sdiff_le_iff]
#align symm_diff_le_iff symmDiff_le_iff
@[simp]
theorem symmDiff_le_sup {a b : α} : a ∆ b ≤ a ⊔ b :=
sup_le_sup sdiff_le sdiff_le
#align symm_diff_le_sup symmDiff_le_sup
theorem symmDiff_eq_sup_sdiff_inf : a ∆ b = (a ⊔ b) \ (a ⊓ b) := by simp [sup_sdiff, symmDiff]
#align symm_diff_eq_sup_sdiff_inf symmDiff_eq_sup_sdiff_inf
theorem Disjoint.symmDiff_eq_sup {a b : α} (h : Disjoint a b) : a ∆ b = a ⊔ b := by
rw [symmDiff, h.sdiff_eq_left, h.sdiff_eq_right]
#align disjoint.symm_diff_eq_sup Disjoint.symmDiff_eq_sup
theorem symmDiff_sdiff : a ∆ b \ c = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) := by
rw [symmDiff, sup_sdiff_distrib, sdiff_sdiff_left, sdiff_sdiff_left]
#align symm_diff_sdiff symmDiff_sdiff
@[simp]
theorem symmDiff_sdiff_inf : a ∆ b \ (a ⊓ b) = a ∆ b := by
rw [symmDiff_sdiff]
simp [symmDiff]
#align symm_diff_sdiff_inf symmDiff_sdiff_inf
@[simp]
theorem symmDiff_sdiff_eq_sup : a ∆ (b \ a) = a ⊔ b := by
rw [symmDiff, sdiff_idem]
exact
le_antisymm (sup_le_sup sdiff_le sdiff_le)
(sup_le le_sdiff_sup <| le_sdiff_sup.trans <| sup_le le_sup_right le_sdiff_sup)
#align symm_diff_sdiff_eq_sup symmDiff_sdiff_eq_sup
@[simp]
theorem sdiff_symmDiff_eq_sup : (a \ b) ∆ b = a ⊔ b := by
rw [symmDiff_comm, symmDiff_sdiff_eq_sup, sup_comm]
#align sdiff_symm_diff_eq_sup sdiff_symmDiff_eq_sup
@[simp]
theorem symmDiff_sup_inf : a ∆ b ⊔ a ⊓ b = a ⊔ b := by
refine' le_antisymm (sup_le symmDiff_le_sup inf_le_sup) _
rw [sup_inf_left, symmDiff]
refine' sup_le (le_inf le_sup_right _) (le_inf _ le_sup_right)
· rw [sup_right_comm]
exact le_sup_of_le_left le_sdiff_sup
· rw [sup_assoc]
exact le_sup_of_le_right le_sdiff_sup
#align symm_diff_sup_inf symmDiff_sup_inf
@[simp]
theorem inf_sup_symmDiff : a ⊓ b ⊔ a ∆ b = a ⊔ b := by rw [sup_comm, symmDiff_sup_inf]
#align inf_sup_symm_diff inf_sup_symmDiff
@[simp]
theorem symmDiff_symmDiff_inf : a ∆ b ∆ (a ⊓ b) = a ⊔ b := by
rw [← symmDiff_sdiff_inf a, sdiff_symmDiff_eq_sup, symmDiff_sup_inf]
#align symm_diff_symm_diff_inf symmDiff_symmDiff_inf
@[simp]
theorem inf_symmDiff_symmDiff : (a ⊓ b) ∆ (a ∆ b) = a ⊔ b := by
rw [symmDiff_comm, symmDiff_symmDiff_inf]
#align inf_symm_diff_symm_diff inf_symmDiff_symmDiff
theorem symmDiff_triangle : a ∆ c ≤ a ∆ b ⊔ b ∆ c := by
refine' (sup_le_sup (sdiff_triangle a b c) <| sdiff_triangle _ b _).trans_eq _
rw [sup_comm (c \ b), sup_sup_sup_comm, symmDiff, symmDiff]
#align symm_diff_triangle symmDiff_triangle
end GeneralizedCoheytingAlgebra
section GeneralizedHeytingAlgebra
variable [GeneralizedHeytingAlgebra α] (a b c d : α)
@[simp]
theorem toDual_bihimp : toDual (a ⇔ b) = toDual a ∆ toDual b :=
rfl
#align to_dual_bihimp toDual_bihimp
@[simp]
theorem ofDual_symmDiff (a b : αᵒᵈ) : ofDual (a ∆ b) = ofDual a ⇔ ofDual b :=
rfl
#align of_dual_symm_diff ofDual_symmDiff
theorem bihimp_comm : a ⇔ b = b ⇔ a := by simp only [(· ⇔ ·), inf_comm]
#align bihimp_comm bihimp_comm
instance bihimp_isCommutative : Std.Commutative (α := α) (· ⇔ ·) :=
⟨bihimp_comm⟩
#align bihimp_is_comm bihimp_isCommutative
@[simp]
theorem bihimp_self : a ⇔ a = ⊤ := by rw [bihimp, inf_idem, himp_self]
#align bihimp_self bihimp_self
@[simp]
theorem bihimp_top : a ⇔ ⊤ = a := by rw [bihimp, himp_top, top_himp, inf_top_eq]
#align bihimp_top bihimp_top
@[simp]
theorem top_bihimp : ⊤ ⇔ a = a := by rw [bihimp_comm, bihimp_top]
#align top_bihimp top_bihimp
@[simp]
theorem bihimp_eq_top {a b : α} : a ⇔ b = ⊤ ↔ a = b :=
@symmDiff_eq_bot αᵒᵈ _ _ _
#align bihimp_eq_top bihimp_eq_top
theorem bihimp_of_le {a b : α} (h : a ≤ b) : a ⇔ b = b ⇨ a := by
rw [bihimp, himp_eq_top_iff.2 h, inf_top_eq]
#align bihimp_of_le bihimp_of_le
theorem bihimp_of_ge {a b : α} (h : b ≤ a) : a ⇔ b = a ⇨ b := by
rw [bihimp, himp_eq_top_iff.2 h, top_inf_eq]
#align bihimp_of_ge bihimp_of_ge
theorem le_bihimp {a b c : α} (hb : a ⊓ b ≤ c) (hc : a ⊓ c ≤ b) : a ≤ b ⇔ c :=
le_inf (le_himp_iff.2 hc) <| le_himp_iff.2 hb
#align le_bihimp le_bihimp
theorem le_bihimp_iff {a b c : α} : a ≤ b ⇔ c ↔ a ⊓ b ≤ c ∧ a ⊓ c ≤ b := by
simp_rw [bihimp, le_inf_iff, le_himp_iff, and_comm]
#align le_bihimp_iff le_bihimp_iff
@[simp]
theorem inf_le_bihimp {a b : α} : a ⊓ b ≤ a ⇔ b :=
inf_le_inf le_himp le_himp
#align inf_le_bihimp inf_le_bihimp
theorem bihimp_eq_inf_himp_inf : a ⇔ b = a ⊔ b ⇨ a ⊓ b := by simp [himp_inf_distrib, bihimp]
#align bihimp_eq_inf_himp_inf bihimp_eq_inf_himp_inf
theorem Codisjoint.bihimp_eq_inf {a b : α} (h : Codisjoint a b) : a ⇔ b = a ⊓ b := by
rw [bihimp, h.himp_eq_left, h.himp_eq_right]
#align codisjoint.bihimp_eq_inf Codisjoint.bihimp_eq_inf
theorem himp_bihimp : a ⇨ b ⇔ c = (a ⊓ c ⇨ b) ⊓ (a ⊓ b ⇨ c) := by
rw [bihimp, himp_inf_distrib, himp_himp, himp_himp]
#align himp_bihimp himp_bihimp
@[simp]
theorem sup_himp_bihimp : a ⊔ b ⇨ a ⇔ b = a ⇔ b := by
rw [himp_bihimp]
simp [bihimp]
#align sup_himp_bihimp sup_himp_bihimp
@[simp]
theorem bihimp_himp_eq_inf : a ⇔ (a ⇨ b) = a ⊓ b :=
@symmDiff_sdiff_eq_sup αᵒᵈ _ _ _
#align bihimp_himp_eq_inf bihimp_himp_eq_inf
@[simp]
theorem himp_bihimp_eq_inf : (b ⇨ a) ⇔ b = a ⊓ b :=
@sdiff_symmDiff_eq_sup αᵒᵈ _ _ _
#align himp_bihimp_eq_inf himp_bihimp_eq_inf
@[simp]
theorem bihimp_inf_sup : a ⇔ b ⊓ (a ⊔ b) = a ⊓ b :=
@symmDiff_sup_inf αᵒᵈ _ _ _
#align bihimp_inf_sup bihimp_inf_sup
@[simp]
theorem sup_inf_bihimp : (a ⊔ b) ⊓ a ⇔ b = a ⊓ b :=
@inf_sup_symmDiff αᵒᵈ _ _ _
#align sup_inf_bihimp sup_inf_bihimp
@[simp]
theorem bihimp_bihimp_sup : a ⇔ b ⇔ (a ⊔ b) = a ⊓ b :=
@symmDiff_symmDiff_inf αᵒᵈ _ _ _
#align bihimp_bihimp_sup bihimp_bihimp_sup
@[simp]
theorem sup_bihimp_bihimp : (a ⊔ b) ⇔ (a ⇔ b) = a ⊓ b :=
@inf_symmDiff_symmDiff αᵒᵈ _ _ _
#align sup_bihimp_bihimp sup_bihimp_bihimp
theorem bihimp_triangle : a ⇔ b ⊓ b ⇔ c ≤ a ⇔ c :=
@symmDiff_triangle αᵒᵈ _ _ _ _
#align bihimp_triangle bihimp_triangle
end GeneralizedHeytingAlgebra
section CoheytingAlgebra
variable [CoheytingAlgebra α] (a : α)
@[simp]
theorem symmDiff_top' : a ∆ ⊤ = ¬a := by simp [symmDiff]
#align symm_diff_top' symmDiff_top'
@[simp]
theorem top_symmDiff' : ⊤ ∆ a = ¬a := by simp [symmDiff]
#align top_symm_diff' top_symmDiff'
@[simp]
theorem hnot_symmDiff_self : (¬a) ∆ a = ⊤ := by
rw [eq_top_iff, symmDiff, hnot_sdiff, sup_sdiff_self]
exact Codisjoint.top_le codisjoint_hnot_left
#align hnot_symm_diff_self hnot_symmDiff_self
@[simp]
theorem symmDiff_hnot_self : a ∆ (¬a) = ⊤ := by rw [symmDiff_comm, hnot_symmDiff_self]
#align symm_diff_hnot_self symmDiff_hnot_self
theorem IsCompl.symmDiff_eq_top {a b : α} (h : IsCompl a b) : a ∆ b = ⊤ := by
rw [h.eq_hnot, hnot_symmDiff_self]
#align is_compl.symm_diff_eq_top IsCompl.symmDiff_eq_top
end CoheytingAlgebra
section HeytingAlgebra
variable [HeytingAlgebra α] (a : α)
@[simp]
theorem bihimp_bot : a ⇔ ⊥ = aᶜ := by simp [bihimp]
#align bihimp_bot bihimp_bot
@[simp]
theorem bot_bihimp : ⊥ ⇔ a = aᶜ := by simp [bihimp]
#align bot_bihimp bot_bihimp
@[simp]
theorem compl_bihimp_self : aᶜ ⇔ a = ⊥ :=
@hnot_symmDiff_self αᵒᵈ _ _
#align compl_bihimp_self compl_bihimp_self
@[simp]
theorem bihimp_hnot_self : a ⇔ aᶜ = ⊥ :=
@symmDiff_hnot_self αᵒᵈ _ _
#align bihimp_hnot_self bihimp_hnot_self
theorem IsCompl.bihimp_eq_bot {a b : α} (h : IsCompl a b) : a ⇔ b = ⊥ := by
rw [h.eq_compl, compl_bihimp_self]
#align is_compl.bihimp_eq_bot IsCompl.bihimp_eq_bot
end HeytingAlgebra
section GeneralizedBooleanAlgebra
variable [GeneralizedBooleanAlgebra α] (a b c d : α)
@[simp]
theorem sup_sdiff_symmDiff : (a ⊔ b) \ a ∆ b = a ⊓ b :=
sdiff_eq_symm inf_le_sup (by rw [symmDiff_eq_sup_sdiff_inf])
#align sup_sdiff_symm_diff sup_sdiff_symmDiff
theorem disjoint_symmDiff_inf : Disjoint (a ∆ b) (a ⊓ b) := by
rw [symmDiff_eq_sup_sdiff_inf]
exact disjoint_sdiff_self_left
#align disjoint_symm_diff_inf disjoint_symmDiff_inf
theorem inf_symmDiff_distrib_left : a ⊓ b ∆ c = (a ⊓ b) ∆ (a ⊓ c) := by
rw [symmDiff_eq_sup_sdiff_inf, inf_sdiff_distrib_left, inf_sup_left, inf_inf_distrib_left,
symmDiff_eq_sup_sdiff_inf]
#align inf_symm_diff_distrib_left inf_symmDiff_distrib_left
theorem inf_symmDiff_distrib_right : a ∆ b ⊓ c = (a ⊓ c) ∆ (b ⊓ c) := by
simp_rw [inf_comm _ c, inf_symmDiff_distrib_left]
#align inf_symm_diff_distrib_right inf_symmDiff_distrib_right
theorem sdiff_symmDiff : c \ a ∆ b = c ⊓ a ⊓ b ⊔ c \ a ⊓ c \ b := by
simp only [(· ∆ ·), sdiff_sdiff_sup_sdiff']
#align sdiff_symm_diff sdiff_symmDiff
theorem sdiff_symmDiff' : c \ a ∆ b = c ⊓ a ⊓ b ⊔ c \ (a ⊔ b) := by
rw [sdiff_symmDiff, sdiff_sup]
#align sdiff_symm_diff' sdiff_symmDiff'
@[simp]
theorem symmDiff_sdiff_left : a ∆ b \ a = b \ a := by
rw [symmDiff_def, sup_sdiff, sdiff_idem, sdiff_sdiff_self, bot_sup_eq]
#align symm_diff_sdiff_left symmDiff_sdiff_left
@[simp]
theorem symmDiff_sdiff_right : a ∆ b \ b = a \ b := by rw [symmDiff_comm, symmDiff_sdiff_left]
#align symm_diff_sdiff_right symmDiff_sdiff_right
@[simp]
theorem sdiff_symmDiff_left : a \ a ∆ b = a ⊓ b := by simp [sdiff_symmDiff]
#align sdiff_symm_diff_left sdiff_symmDiff_left
@[simp]
theorem sdiff_symmDiff_right : b \ a ∆ b = a ⊓ b := by
rw [symmDiff_comm, inf_comm, sdiff_symmDiff_left]
#align sdiff_symm_diff_right sdiff_symmDiff_right
theorem symmDiff_eq_sup : a ∆ b = a ⊔ b ↔ Disjoint a b := by
refine' ⟨fun h => _, Disjoint.symmDiff_eq_sup⟩
rw [symmDiff_eq_sup_sdiff_inf, sdiff_eq_self_iff_disjoint] at h
exact h.of_disjoint_inf_of_le le_sup_left
#align symm_diff_eq_sup symmDiff_eq_sup
@[simp]
theorem le_symmDiff_iff_left : a ≤ a ∆ b ↔ Disjoint a b := by
refine' ⟨fun h => _, fun h => h.symmDiff_eq_sup.symm ▸ le_sup_left⟩
rw [symmDiff_eq_sup_sdiff_inf] at h
exact disjoint_iff_inf_le.mpr (le_sdiff_iff.1 <| inf_le_of_left_le h).le
#align le_symm_diff_iff_left le_symmDiff_iff_left
@[simp]
theorem le_symmDiff_iff_right : b ≤ a ∆ b ↔ Disjoint a b := by
rw [symmDiff_comm, le_symmDiff_iff_left, disjoint_comm]
#align le_symm_diff_iff_right le_symmDiff_iff_right
theorem symmDiff_symmDiff_left :
a ∆ b ∆ c = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) ⊔ c \ (a ⊔ b) ⊔ a ⊓ b ⊓ c :=
calc
a ∆ b ∆ c = a ∆ b \ c ⊔ c \ a ∆ b := symmDiff_def _ _
_ = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) ⊔ (c \ (a ⊔ b) ⊔ c ⊓ a ⊓ b) := by
{ rw [sdiff_symmDiff', sup_comm (c ⊓ a ⊓ b), symmDiff_sdiff] }
_ = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) ⊔ c \ (a ⊔ b) ⊔ a ⊓ b ⊓ c := by ac_rfl
#align symm_diff_symm_diff_left symmDiff_symmDiff_left
theorem symmDiff_symmDiff_right :
a ∆ (b ∆ c) = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) ⊔ c \ (a ⊔ b) ⊔ a ⊓ b ⊓ c :=
calc
a ∆ (b ∆ c) = a \ b ∆ c ⊔ b ∆ c \ a := symmDiff_def _ _
_ = a \ (b ⊔ c) ⊔ a ⊓ b ⊓ c ⊔ (b \ (c ⊔ a) ⊔ c \ (b ⊔ a)) := by
{ rw [sdiff_symmDiff', sup_comm (a ⊓ b ⊓ c), symmDiff_sdiff] }
_ = a \ (b ⊔ c) ⊔ b \ (a ⊔ c) ⊔ c \ (a ⊔ b) ⊔ a ⊓ b ⊓ c := by ac_rfl
#align symm_diff_symm_diff_right symmDiff_symmDiff_right
theorem symmDiff_assoc : a ∆ b ∆ c = a ∆ (b ∆ c) := by
rw [symmDiff_symmDiff_left, symmDiff_symmDiff_right]
#align symm_diff_assoc symmDiff_assoc
instance symmDiff_isAssociative : Std.Associative (α := α) (· ∆ ·) :=
⟨symmDiff_assoc⟩
#align symm_diff_is_assoc symmDiff_isAssociative
theorem symmDiff_left_comm : a ∆ (b ∆ c) = b ∆ (a ∆ c) := by
simp_rw [← symmDiff_assoc, symmDiff_comm]
#align symm_diff_left_comm symmDiff_left_comm
theorem symmDiff_right_comm : a ∆ b ∆ c = a ∆ c ∆ b := by simp_rw [symmDiff_assoc, symmDiff_comm]
#align symm_diff_right_comm symmDiff_right_comm
theorem symmDiff_symmDiff_symmDiff_comm : a ∆ b ∆ (c ∆ d) = a ∆ c ∆ (b ∆ d) := by
simp_rw [symmDiff_assoc, symmDiff_left_comm]
#align symm_diff_symm_diff_symm_diff_comm symmDiff_symmDiff_symmDiff_comm
@[simp]
theorem symmDiff_symmDiff_cancel_left : a ∆ (a ∆ b) = b := by simp [← symmDiff_assoc]
#align symm_diff_symm_diff_cancel_left symmDiff_symmDiff_cancel_left
@[simp]
theorem symmDiff_symmDiff_cancel_right : b ∆ a ∆ a = b := by simp [symmDiff_assoc]
#align symm_diff_symm_diff_cancel_right symmDiff_symmDiff_cancel_right
@[simp]
theorem symmDiff_symmDiff_self' : a ∆ b ∆ a = b := by
rw [symmDiff_comm, symmDiff_symmDiff_cancel_left]
#align symm_diff_symm_diff_self' symmDiff_symmDiff_self'
theorem symmDiff_left_involutive (a : α) : Involutive (· ∆ a) :=
symmDiff_symmDiff_cancel_right _
#align symm_diff_left_involutive symmDiff_left_involutive
theorem symmDiff_right_involutive (a : α) : Involutive (a ∆ ·) :=
symmDiff_symmDiff_cancel_left _
#align symm_diff_right_involutive symmDiff_right_involutive
theorem symmDiff_left_injective (a : α) : Injective (· ∆ a) :=
Function.Involutive.injective (symmDiff_left_involutive a)
#align symm_diff_left_injective symmDiff_left_injective
theorem symmDiff_right_injective (a : α) : Injective (a ∆ ·) :=
Function.Involutive.injective (symmDiff_right_involutive _)
#align symm_diff_right_injective symmDiff_right_injective
theorem symmDiff_left_surjective (a : α) : Surjective (· ∆ a) :=
Function.Involutive.surjective (symmDiff_left_involutive _)
#align symm_diff_left_surjective symmDiff_left_surjective
theorem symmDiff_right_surjective (a : α) : Surjective (a ∆ ·) :=
Function.Involutive.surjective (symmDiff_right_involutive _)
#align symm_diff_right_surjective symmDiff_right_surjective
variable {a b c}
@[simp]
theorem symmDiff_left_inj : a ∆ b = c ∆ b ↔ a = c :=
(symmDiff_left_injective _).eq_iff
#align symm_diff_left_inj symmDiff_left_inj
@[simp]
theorem symmDiff_right_inj : a ∆ b = a ∆ c ↔ b = c :=
(symmDiff_right_injective _).eq_iff
#align symm_diff_right_inj symmDiff_right_inj
@[simp]
theorem symmDiff_eq_left : a ∆ b = a ↔ b = ⊥ :=
calc
a ∆ b = a ↔ a ∆ b = a ∆ ⊥ := by rw [symmDiff_bot]
_ ↔ b = ⊥ := by rw [symmDiff_right_inj]
#align symm_diff_eq_left symmDiff_eq_left
@[simp]
theorem symmDiff_eq_right : a ∆ b = b ↔ a = ⊥ := by rw [symmDiff_comm, symmDiff_eq_left]
#align symm_diff_eq_right symmDiff_eq_right
protected theorem Disjoint.symmDiff_left (ha : Disjoint a c) (hb : Disjoint b c) :
Disjoint (a ∆ b) c := by
rw [symmDiff_eq_sup_sdiff_inf]
exact (ha.sup_left hb).disjoint_sdiff_left
#align disjoint.symm_diff_left Disjoint.symmDiff_left
protected theorem Disjoint.symmDiff_right (ha : Disjoint a b) (hb : Disjoint a c) :
Disjoint a (b ∆ c) :=
(ha.symm.symmDiff_left hb.symm).symm
#align disjoint.symm_diff_right Disjoint.symmDiff_right
theorem symmDiff_eq_iff_sdiff_eq (ha : a ≤ c) : a ∆ b = c ↔ c \ a = b := by
rw [← symmDiff_of_le ha]
exact ((symmDiff_right_involutive a).toPerm _).apply_eq_iff_eq_symm_apply.trans eq_comm
#align symm_diff_eq_iff_sdiff_eq symmDiff_eq_iff_sdiff_eq
end GeneralizedBooleanAlgebra
section BooleanAlgebra
variable [BooleanAlgebra α] (a b c d : α)
/- `CogeneralizedBooleanAlgebra` isn't actually a typeclass, but the lemmas in here are dual to
the `GeneralizedBooleanAlgebra` ones -/
section CogeneralizedBooleanAlgebra
@[simp]
theorem inf_himp_bihimp : a ⇔ b ⇨ a ⊓ b = a ⊔ b :=
@sup_sdiff_symmDiff αᵒᵈ _ _ _
#align inf_himp_bihimp inf_himp_bihimp
theorem codisjoint_bihimp_sup : Codisjoint (a ⇔ b) (a ⊔ b) :=
@disjoint_symmDiff_inf αᵒᵈ _ _ _
#align codisjoint_bihimp_sup codisjoint_bihimp_sup
@[simp]
theorem himp_bihimp_left : a ⇨ a ⇔ b = a ⇨ b :=
@symmDiff_sdiff_left αᵒᵈ _ _ _
#align himp_bihimp_left himp_bihimp_left
@[simp]
theorem himp_bihimp_right : b ⇨ a ⇔ b = b ⇨ a :=
@symmDiff_sdiff_right αᵒᵈ _ _ _
#align himp_bihimp_right himp_bihimp_right
@[simp]
theorem bihimp_himp_left : a ⇔ b ⇨ a = a ⊔ b :=
@sdiff_symmDiff_left αᵒᵈ _ _ _
#align bihimp_himp_left bihimp_himp_left
@[simp]
theorem bihimp_himp_right : a ⇔ b ⇨ b = a ⊔ b :=
@sdiff_symmDiff_right αᵒᵈ _ _ _
#align bihimp_himp_right bihimp_himp_right
@[simp]
theorem bihimp_eq_inf : a ⇔ b = a ⊓ b ↔ Codisjoint a b :=
@symmDiff_eq_sup αᵒᵈ _ _ _
#align bihimp_eq_inf bihimp_eq_inf
@[simp]
theorem bihimp_le_iff_left : a ⇔ b ≤ a ↔ Codisjoint a b :=
@le_symmDiff_iff_left αᵒᵈ _ _ _
#align bihimp_le_iff_left bihimp_le_iff_left
@[simp]
theorem bihimp_le_iff_right : a ⇔ b ≤ b ↔ Codisjoint a b :=
@le_symmDiff_iff_right αᵒᵈ _ _ _
#align bihimp_le_iff_right bihimp_le_iff_right
theorem bihimp_assoc : a ⇔ b ⇔ c = a ⇔ (b ⇔ c) :=
@symmDiff_assoc αᵒᵈ _ _ _ _
#align bihimp_assoc bihimp_assoc
instance bihimp_isAssociative : Std.Associative (α := α) (· ⇔ ·) :=
⟨bihimp_assoc⟩
#align bihimp_is_assoc bihimp_isAssociative
theorem bihimp_left_comm : a ⇔ (b ⇔ c) = b ⇔ (a ⇔ c) := by simp_rw [← bihimp_assoc, bihimp_comm]
#align bihimp_left_comm bihimp_left_comm
theorem bihimp_right_comm : a ⇔ b ⇔ c = a ⇔ c ⇔ b := by simp_rw [bihimp_assoc, bihimp_comm]
#align bihimp_right_comm bihimp_right_comm
theorem bihimp_bihimp_bihimp_comm : a ⇔ b ⇔ (c ⇔ d) = a ⇔ c ⇔ (b ⇔ d) := by
simp_rw [bihimp_assoc, bihimp_left_comm]
#align bihimp_bihimp_bihimp_comm bihimp_bihimp_bihimp_comm
@[simp]
theorem bihimp_bihimp_cancel_left : a ⇔ (a ⇔ b) = b := by simp [← bihimp_assoc]
#align bihimp_bihimp_cancel_left bihimp_bihimp_cancel_left
@[simp]
theorem bihimp_bihimp_cancel_right : b ⇔ a ⇔ a = b := by simp [bihimp_assoc]
#align bihimp_bihimp_cancel_right bihimp_bihimp_cancel_right
@[simp]
theorem bihimp_bihimp_self : a ⇔ b ⇔ a = b := by rw [bihimp_comm, bihimp_bihimp_cancel_left]
#align bihimp_bihimp_self bihimp_bihimp_self
theorem bihimp_left_involutive (a : α) : Involutive (· ⇔ a) :=
bihimp_bihimp_cancel_right _
#align bihimp_left_involutive bihimp_left_involutive
theorem bihimp_right_involutive (a : α) : Involutive (a ⇔ ·) :=
bihimp_bihimp_cancel_left _
#align bihimp_right_involutive bihimp_right_involutive
theorem bihimp_left_injective (a : α) : Injective (· ⇔ a) :=
@symmDiff_left_injective αᵒᵈ _ _
#align bihimp_left_injective bihimp_left_injective
theorem bihimp_right_injective (a : α) : Injective (a ⇔ ·) :=
@symmDiff_right_injective αᵒᵈ _ _
#align bihimp_right_injective bihimp_right_injective
theorem bihimp_left_surjective (a : α) : Surjective (· ⇔ a) :=
@symmDiff_left_surjective αᵒᵈ _ _
#align bihimp_left_surjective bihimp_left_surjective
theorem bihimp_right_surjective (a : α) : Surjective (a ⇔ ·) :=
@symmDiff_right_surjective αᵒᵈ _ _
#align bihimp_right_surjective bihimp_right_surjective
variable {a b c}
@[simp]
theorem bihimp_left_inj : a ⇔ b = c ⇔ b ↔ a = c :=
(bihimp_left_injective _).eq_iff
#align bihimp_left_inj bihimp_left_inj
@[simp]
theorem bihimp_right_inj : a ⇔ b = a ⇔ c ↔ b = c :=
(bihimp_right_injective _).eq_iff
#align bihimp_right_inj bihimp_right_inj
@[simp]
theorem bihimp_eq_left : a ⇔ b = a ↔ b = ⊤ :=
@symmDiff_eq_left αᵒᵈ _ _ _
#align bihimp_eq_left bihimp_eq_left
@[simp]
theorem bihimp_eq_right : a ⇔ b = b ↔ a = ⊤ :=
@symmDiff_eq_right αᵒᵈ _ _ _
#align bihimp_eq_right bihimp_eq_right
protected theorem Codisjoint.bihimp_left (ha : Codisjoint a c) (hb : Codisjoint b c) :
Codisjoint (a ⇔ b) c :=
(ha.inf_left hb).mono_left inf_le_bihimp
#align codisjoint.bihimp_left Codisjoint.bihimp_left
protected theorem Codisjoint.bihimp_right (ha : Codisjoint a b) (hb : Codisjoint a c) :
Codisjoint a (b ⇔ c) :=
(ha.inf_right hb).mono_right inf_le_bihimp
#align codisjoint.bihimp_right Codisjoint.bihimp_right
end CogeneralizedBooleanAlgebra
theorem symmDiff_eq : a ∆ b = a ⊓ bᶜ ⊔ b ⊓ aᶜ := by simp only [(· ∆ ·), sdiff_eq]
#align symm_diff_eq symmDiff_eq
theorem bihimp_eq : a ⇔ b = (a ⊔ bᶜ) ⊓ (b ⊔ aᶜ) := by simp only [(· ⇔ ·), himp_eq]
#align bihimp_eq bihimp_eq
theorem symmDiff_eq' : a ∆ b = (a ⊔ b) ⊓ (aᶜ ⊔ bᶜ) := by
rw [symmDiff_eq_sup_sdiff_inf, sdiff_eq, compl_inf]
#align symm_diff_eq' symmDiff_eq'
theorem bihimp_eq' : a ⇔ b = a ⊓ b ⊔ aᶜ ⊓ bᶜ :=
@symmDiff_eq' αᵒᵈ _ _ _
#align bihimp_eq' bihimp_eq'
theorem symmDiff_top : a ∆ ⊤ = aᶜ :=
symmDiff_top' _
#align symm_diff_top symmDiff_top
theorem top_symmDiff : ⊤ ∆ a = aᶜ :=
top_symmDiff' _
#align top_symm_diff top_symmDiff
@[simp]
theorem compl_symmDiff : (a ∆ b)ᶜ = a ⇔ b := by
simp_rw [symmDiff, compl_sup_distrib, compl_sdiff, bihimp, inf_comm]
#align compl_symm_diff compl_symmDiff
@[simp]
theorem compl_bihimp : (a ⇔ b)ᶜ = a ∆ b :=
@compl_symmDiff αᵒᵈ _ _ _
#align compl_bihimp compl_bihimp
@[simp]
theorem compl_symmDiff_compl : aᶜ ∆ bᶜ = a ∆ b :=
(sup_comm _ _).trans <| by simp_rw [compl_sdiff_compl, sdiff_eq, symmDiff_eq]
#align compl_symm_diff_compl compl_symmDiff_compl
@[simp]
theorem compl_bihimp_compl : aᶜ ⇔ bᶜ = a ⇔ b :=
@compl_symmDiff_compl αᵒᵈ _ _ _
#align compl_bihimp_compl compl_bihimp_compl
@[simp]
theorem symmDiff_eq_top : a ∆ b = ⊤ ↔ IsCompl a b := by
rw [symmDiff_eq', ← compl_inf, inf_eq_top_iff, compl_eq_top, isCompl_iff, disjoint_iff,
codisjoint_iff, and_comm]
#align symm_diff_eq_top symmDiff_eq_top
@[simp]
theorem bihimp_eq_bot : a ⇔ b = ⊥ ↔ IsCompl a b := by
rw [bihimp_eq', ← compl_sup, sup_eq_bot_iff, compl_eq_bot, isCompl_iff, disjoint_iff,
codisjoint_iff]
#align bihimp_eq_bot bihimp_eq_bot
@[simp]
theorem compl_symmDiff_self : aᶜ ∆ a = ⊤ :=
hnot_symmDiff_self _
#align compl_symm_diff_self compl_symmDiff_self
@[simp]
theorem symmDiff_compl_self : a ∆ aᶜ = ⊤ :=
symmDiff_hnot_self _
#align symm_diff_compl_self symmDiff_compl_self
theorem symmDiff_symmDiff_right' :
a ∆ (b ∆ c) = a ⊓ b ⊓ c ⊔ a ⊓ bᶜ ⊓ cᶜ ⊔ aᶜ ⊓ b ⊓ cᶜ ⊔ aᶜ ⊓ bᶜ ⊓ c :=
calc
a ∆ (b ∆ c) = a ⊓ (b ⊓ c ⊔ bᶜ ⊓ cᶜ) ⊔ (b ⊓ cᶜ ⊔ c ⊓ bᶜ) ⊓ aᶜ := by
{ rw [symmDiff_eq, compl_symmDiff, bihimp_eq', symmDiff_eq] }
_ = a ⊓ b ⊓ c ⊔ a ⊓ bᶜ ⊓ cᶜ ⊔ b ⊓ cᶜ ⊓ aᶜ ⊔ c ⊓ bᶜ ⊓ aᶜ := by
{ rw [inf_sup_left, inf_sup_right, ← sup_assoc, ← inf_assoc, ← inf_assoc] }
_ = a ⊓ b ⊓ c ⊔ a ⊓ bᶜ ⊓ cᶜ ⊔ aᶜ ⊓ b ⊓ cᶜ ⊔ aᶜ ⊓ bᶜ ⊓ c := (by
congr 1
· congr 1
rw [inf_comm, inf_assoc]
· apply inf_left_right_swap)
#align symm_diff_symm_diff_right' symmDiff_symmDiff_right'
variable {a b c}
theorem Disjoint.le_symmDiff_sup_symmDiff_left (h : Disjoint a b) : c ≤ a ∆ c ⊔ b ∆ c := by
trans c \ (a ⊓ b)
· rw [h.eq_bot, sdiff_bot]
· rw [sdiff_inf]
exact sup_le_sup le_sup_right le_sup_right
#align disjoint.le_symm_diff_sup_symm_diff_left Disjoint.le_symmDiff_sup_symmDiff_left
theorem Disjoint.le_symmDiff_sup_symmDiff_right (h : Disjoint b c) : a ≤ a ∆ b ⊔ a ∆ c := by
simp_rw [symmDiff_comm a]
exact h.le_symmDiff_sup_symmDiff_left
#align disjoint.le_symm_diff_sup_symm_diff_right Disjoint.le_symmDiff_sup_symmDiff_right
theorem Codisjoint.bihimp_inf_bihimp_le_left (h : Codisjoint a b) : a ⇔ c ⊓ b ⇔ c ≤ c :=
h.dual.le_symmDiff_sup_symmDiff_left
#align codisjoint.bihimp_inf_bihimp_le_left Codisjoint.bihimp_inf_bihimp_le_left
theorem Codisjoint.bihimp_inf_bihimp_le_right (h : Codisjoint b c) : a ⇔ b ⊓ a ⇔ c ≤ a :=
h.dual.le_symmDiff_sup_symmDiff_right
#align codisjoint.bihimp_inf_bihimp_le_right Codisjoint.bihimp_inf_bihimp_le_right
end BooleanAlgebra
/-! ### Prod -/
section Prod
@[simp]
theorem symmDiff_fst [GeneralizedCoheytingAlgebra α] [GeneralizedCoheytingAlgebra β]
(a b : α × β) : (a ∆ b).1 = a.1 ∆ b.1 :=
rfl
#align symm_diff_fst symmDiff_fst
@[simp]
theorem symmDiff_snd [GeneralizedCoheytingAlgebra α] [GeneralizedCoheytingAlgebra β]
(a b : α × β) : (a ∆ b).2 = a.2 ∆ b.2 :=
rfl
#align symm_diff_snd symmDiff_snd
@[simp]
theorem bihimp_fst [GeneralizedHeytingAlgebra α] [GeneralizedHeytingAlgebra β] (a b : α × β) :
(a ⇔ b).1 = a.1 ⇔ b.1 :=
rfl
#align bihimp_fst bihimp_fst
@[simp]
theorem bihimp_snd [GeneralizedHeytingAlgebra α] [GeneralizedHeytingAlgebra β] (a b : α × β) :
(a ⇔ b).2 = a.2 ⇔ b.2 :=
rfl
#align bihimp_snd bihimp_snd
end Prod
/-! ### Pi -/
namespace Pi
theorem symmDiff_def [∀ i, GeneralizedCoheytingAlgebra (π i)] (a b : ∀ i, π i) :
a ∆ b = fun i => a i ∆ b i :=
rfl
#align pi.symm_diff_def Pi.symmDiff_def
theorem bihimp_def [∀ i, GeneralizedHeytingAlgebra (π i)] (a b : ∀ i, π i) :
a ⇔ b = fun i => a i ⇔ b i :=
rfl
#align pi.bihimp_def Pi.bihimp_def
@[simp]
theorem symmDiff_apply [∀ i, GeneralizedCoheytingAlgebra (π i)] (a b : ∀ i, π i) (i : ι) :
(a ∆ b) i = a i ∆ b i :=
rfl
#align pi.symm_diff_apply Pi.symmDiff_apply
@[simp]
theorem bihimp_apply [∀ i, GeneralizedHeytingAlgebra (π i)] (a b : ∀ i, π i) (i : ι) :
(a ⇔ b) i = a i ⇔ b i :=
rfl
#align pi.bihimp_apply Pi.bihimp_apply
end Pi