ATBR.Model_Languages
(**************************************************************************)
(* This is part of ATBR, it is distributed under the terms of the *)
(* GNU Lesser General Public License version 3 *)
(* (see file LICENSE for more details) *)
(* *)
(* Copyright 2009-2011: Thomas Braibant, Damien Pous. *)
(**************************************************************************)
(* This is part of ATBR, it is distributed under the terms of the *)
(* GNU Lesser General Public License version 3 *)
(* (see file LICENSE for more details) *)
(* *)
(* Copyright 2009-2011: Thomas Braibant, Damien Pous. *)
(**************************************************************************)
Languages form a model of Kleene algebras
Require Import Common.
Require Import Classes.
Require Import MxGraph.
Require Converse.
Require Import List.
Set Implicit Arguments.
Unset Strict Implicit.
Section Def.
Context {A: Type}.
(* a language is a predicate of words, i.e., list of letters *)
Definition lang := list A -> Prop.
Definition lang_equal (L L': lang): Prop := forall x, L x <-> L' x.
Definition lang_union (L L': lang): lang := fun x => L x \/ L' x.
Definition lang_Union I (L: I -> lang): lang := fun x => exists i, L i x.
Definition lang_inter (L L': lang): lang := fun x => L x /\ L' x.
Definition lang_comp (L L': lang): lang := fun x => exists2 u, L u & exists2 v, L' v & x=u++v.
Definition lang_conv (L: lang): lang := fun x => L (rev x).
Definition lang_id: lang := fun x => x=nil.
Definition lang_empty: lang := fun x => False.
Definition lang_top: lang := fun x => True.
Fixpoint lang_iter (L: lang) n: lang :=
match n with
| 0 => lang_id
| S n => lang_comp (lang_iter L n) L
end.
Definition lang_star (L: lang): lang := fun x => exists n, lang_iter L n x.
Program Instance lang_Graph: Graph := {
T := unit;
X A B := lang;
equal A B := lang_equal
}.
Next Obligation.
constructor; unfold lang_equal; repeat intro; firstorder.
Qed.
Instance lang_SemiLattice_Ops: SemiLattice_Ops lang_Graph := {
plus A B := lang_union;
zero A B := lang_empty
}.
Instance lang_Monoid_Ops: Monoid_Ops lang_Graph := {
dot A B C := lang_comp;
one A := lang_id
}.
Instance lang_Star_Op: Star_Op lang_Graph := {
star A := lang_star
}.
Instance lang_Converse_Op: Converse_Op lang_Graph := {
conv A B := lang_conv
}.
Transparent equal.
Instance lang_SemiLattice: SemiLattice lang_Graph.
Proof.
constructor; compute; firstorder.
Qed.
Instance lang_ConverseSemiRing: ConverseIdemSemiRing lang_Graph.
Proof.
constructor; (exact lang_SemiLattice || (try solve [intros; compute; firstorder])).
intros ? ? ? ? L M N x. simpl. unfold lang_comp.
split; intros [u Hu [v Hv ->]].
destruct Hv as [v' Hv [w Hw ->]]. repeat eexists; eauto. symmetry. apply app_ass.
destruct Hu as [v' Hv' [w Hw ->]]. repeat eexists; eauto. apply app_ass.
intros ? ? L x. simpl. unfold lang_comp.
split; intro H.
destruct H as [u -> [v Hv ->]]. assumption.
exists nil; eauto. reflexivity.
intros ? ? L x. unfold conv, lang_Converse_Op, lang_conv. rewrite rev_involutive. reflexivity.
intros ? ? ? L M x. simpl. unfold conv, lang_Converse_Op, lang_conv, lang_comp.
split; intros [u Hu [v Hv H]].
assert (Hx: x=rev v++rev u). rewrite <- distr_rev, <- H, rev_involutive. reflexivity.
rewrite Hx. repeat eexists; rewrite rev_involutive; assumption.
rewrite H, distr_rev. eauto.
Qed.
Definition lang_IdemSemiRing: IdemSemiRing lang_Graph := Converse.CISR_ISR.
Notation LX := (@X lang_Graph tt tt).
Lemma lang_leq n m: forall (a b: @X (lang_Graph) n m), a<==b <-> forall x, a x -> b x.
Proof. compute. firstorder. Qed.
Lemma lang_Union_spec I (L: I -> LX): forall L': LX, (lang_Union L: LX) <== L' <-> forall i, L i <== L'.
Proof.
intros. split; intro H.
intro j. rewrite <- H. apply <- lang_leq. intros w Hw. exists j; assumption.
apply <- lang_leq. intros w [j Hw]. setoid_rewrite lang_leq in H. eauto.
Qed.
Lemma leq_lang_Union I (L: I -> LX): forall i, L i <== lang_Union L.
Proof.
intros. apply -> (lang_Union_spec L). apply plus_idem.
Qed.
Instance lang_ConverseKleeneAlgebra: ConverseKleeneAlgebra lang_Graph.
Proof.
constructor;
first [
exact lang_ConverseSemiRing |
intros
].
intros p; split; intro H.
destruct H as [H|[u [n Hu] [v Hv H]]].
exists O; trivial.
exists (S n). exists u; trivial. exists v; trivial.
destruct H as [[|n] H].
left; trivial.
right. destruct H as [u Hu [v Hv H]]. exists u; trivial. exists n; trivial. exists v; trivial.
apply <- lang_leq. intros w [u [n Hu] [v Hv ->]].
revert u Hu v Hv. induction n; intros u Hu v Hv.
rewrite Hu. trivial.
destruct Hu as [x Hx [y Hy ->]].
rewrite app_ass. apply IHn; trivial.
apply -> lang_leq; eauto. repeat eexists; trivial.
Qed.
Definition lang_KleeneAlgebra: KleeneAlgebra lang_Graph := Converse.CKA_KA.
End Def.
Import this module to work with languages
Module Load.
Existing Instance lang_Graph.
Existing Instance lang_SemiLattice_Ops.
Existing Instance lang_Monoid_Ops.
Existing Instance lang_Converse_Op.
Existing Instance lang_SemiLattice.
Existing Instance lang_Star_Op.
Existing Instance lang_KleeneAlgebra.
Canonical Structure lang_Graph.
Transparent equal plus dot one zero star.
Notation LX A := (@X (@lang_Graph A) tt tt).
Notation LMX A n m := (@X (@mx_Graph (@lang_Graph A) tt) (n%nat) (m%nat)).
Ltac fold_langAlg A :=
change (@lang_equal A) with (@equal (@lang_Graph A) tt tt);
change (@lang_id A) with (@one (@lang_Graph A) (@lang_Monoid_Ops A) tt);
change (@lang_comp A) with (@dot (@lang_Graph A) (@lang_Monoid_Ops A) tt tt tt);
change (@lang_union A) with (@plus (@lang_Graph A) (@lang_SemiLattice_Ops A) tt tt);
change (@lang_empty A) with (@zero (@lang_Graph A) (@lang_SemiLattice_Ops A) tt tt);
change (@lang_star A) with (@star (@lang_Graph A) (@lang_Star_Op A) tt).
End Load.
Existing Instance lang_Graph.
Existing Instance lang_SemiLattice_Ops.
Existing Instance lang_Monoid_Ops.
Existing Instance lang_Converse_Op.
Existing Instance lang_SemiLattice.
Existing Instance lang_Star_Op.
Existing Instance lang_KleeneAlgebra.
Canonical Structure lang_Graph.
Transparent equal plus dot one zero star.
Notation LX A := (@X (@lang_Graph A) tt tt).
Notation LMX A n m := (@X (@mx_Graph (@lang_Graph A) tt) (n%nat) (m%nat)).
Ltac fold_langAlg A :=
change (@lang_equal A) with (@equal (@lang_Graph A) tt tt);
change (@lang_id A) with (@one (@lang_Graph A) (@lang_Monoid_Ops A) tt);
change (@lang_comp A) with (@dot (@lang_Graph A) (@lang_Monoid_Ops A) tt tt tt);
change (@lang_union A) with (@plus (@lang_Graph A) (@lang_SemiLattice_Ops A) tt tt);
change (@lang_empty A) with (@zero (@lang_Graph A) (@lang_SemiLattice_Ops A) tt tt);
change (@lang_star A) with (@star (@lang_Graph A) (@lang_Star_Op A) tt).
End Load.