Library RelationAlgebra.boolean
Canonical Structure bool_lattice_ops: lattice.ops := {|
leq := le_bool;
weq := eq;
cup := orb;
cap := andb;
neg := negb;
bot := false;
top := true
|}.
is_true is a bounded distributive lattice homomorphism from bool to Prop.
(Actually a Boolean lattice homomorphism, but we don't need it here.)
#[export] Instance mm_bool_Prop: morphism BDL is_true.
Proof.
constructor; simpl.
now auto.
intros ? ?. now rewrite eq_bool_iff.
intros _ [|] [|]; firstorder.
intros _ [|] [|]; firstorder.
intros _. easy.
tauto.
intros _ [|]. firstorder auto with bool. easy.
Qed.
Proof.
constructor; simpl.
now auto.
intros ? ?. now rewrite eq_bool_iff.
intros _ [|] [|]; firstorder.
intros _ [|] [|]; firstorder.
intros _. easy.
tauto.
intros _ [|]. firstorder auto with bool. easy.
Qed.
we get most lattice laws by the faithful embedding into Prop
#[export] Instance bool_lattice_laws: lattice.laws (BL+STR+CNV+DIV) bool_lattice_ops.
Proof.
assert(H: lattice.laws BDL bool_lattice_ops).
apply (laws_of_injective_morphism is_true mm_bool_Prop).
auto.
intros x y. apply eq_bool_iff.
constructor; try apply H; (try now left); intros _ [|]; reflexivity.
Qed.
Proof.
assert(H: lattice.laws BDL bool_lattice_ops).
apply (laws_of_injective_morphism is_true mm_bool_Prop).
auto.
intros x y. apply eq_bool_iff.
constructor; try apply H; (try now left); intros _ [|]; reflexivity.
Qed.
simple characterisation of finite sups and infs in bool
Lemma is_true_sup I J (f: I → bool): \sup_(i\in J) f i ↔ (∃ i, List.In i J ∧ f i).
Proof.
unfold is_true. induction J; simpl. firstorder; discriminate.
rewrite Bool.orb_true_iff. firstorder congruence.
Qed.
Lemma is_true_inf I J (f: I → bool): \inf_(i\in J) f i ↔ (∀ i, List.In i J → f i).
Proof.
unfold is_true. induction J; simpl. firstorder.
rewrite Bool.andb_true_iff. firstorder congruence.
Qed.
Boolean as a (flat) monoid
this is useful:- to construct boolean matrices,
- to consider regex.epsilon as a functor)
note that the trivial type information is simply ignored
Canonical Structure bool_ops: monoid.ops := {|
ob := bool_unit;
mor n m := bool_lattice_ops;
dot n m p := andb;
one n := true;
itr n x := x;
str n x := true;
cnv n m x := x;
ldv n m p x y := !x ⊔ y;
rdv n m p x y := !x ⊔ y
|}.
ob := bool_unit;
mor n m := bool_lattice_ops;
dot n m p := andb;
one n := true;
itr n x := x;
str n x := true;
cnv n m x := x;
ldv n m p x y := !x ⊔ y;
rdv n m p x y := !x ⊔ y
|}.
shorthand for bool, when a morphism is expected
we actually have all laws on bool
#[export] Instance bool_laws: laws (BL+STR+CNV+DIV) bool_ops.
Proof.
constructor; (try now left);repeat right; intros.
apply bool_lattice_laws.
apply capA.
apply captx.
apply weq_leq. simpl. apply capC.
reflexivity.
now intros ? ? ?.
reflexivity.
all: try setoid_rewrite <- le_bool_spec.
all: try case x; try case y; try case z; reflexivity.
Qed.
Proof.
constructor; (try now left);repeat right; intros.
apply bool_lattice_laws.
apply capA.
apply captx.
apply weq_leq. simpl. apply capC.
reflexivity.
now intros ? ? ?.
reflexivity.
all: try setoid_rewrite <- le_bool_spec.
all: try case x; try case y; try case z; reflexivity.
Qed.
properties of the ofbool injection
Section ofbool.
Open Scope bool_scope.
Implicit Types a b c: bool.
Context {X: ops} {l} {L: laws l X} {n: ob X}.
Notation ofbool := (@ofbool X n).
Lemma andb_dot `{BOT ≪ l} a b: ofbool (a&&b) ≡ ofbool a ⋅ ofbool b.
Proof.
symmetry. case a. apply dot1x.
apply antisym. now apply weq_leq, dot0x. apply leq_bx.
Qed.
Lemma orb_pls `{CUP+BOT ≪ l} a b: ofbool (a||b) ≡ ofbool a + ofbool b.
Proof. symmetry. case a; simpl. case b; simpl; lattice. lattice. Qed.
#[export] Instance ofbool_leq `{BOT ≪ l}: Proper (leq ==> leq) ofbool.
Proof. intros [|] b E; simpl. now rewrite E. apply leq_bx. Qed.
Lemma dot_ofboolx `{BOT ≪ l} b (x: X n n): ofbool b⋅x ≡ x⋅ofbool b.
Proof. case b; simpl. now rewrite dot1x, dotx1. now rewrite dot0x, dotx0. Qed.
End ofbool.
is_true is also monotone