(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
(* fonction de suppression des états non coaccessibles *)
Fixpoint non_coacc_kill (d : preDTA) (m : Map bool) {struct m} : preDTA :=
match d, m with
| M0, M0 => M0 state
| M1 a s, M1 a' b => if N.eqb a a' && b then M1 state a s else M0 state
| M2 x y, M2 z t => M2 state (non_coacc_kill x z) (non_coacc_kill y t)
| _, _ => M0 state
end.
Definition predta_kill_non_coacc (d : preDTA) (a : ad) : preDTA :=
non_coacc_kill d (predta_coacc_states d a).
Definition dta_kill_non_coacc (d : DTA) : DTA :=
match d with
| dta p a => dta (predta_kill_non_coacc p a) a
end.
Definition predta_kill_non_coacc_lazy (d : preDTA)
(a : ad) : preDTA := non_coacc_kill d (predta_coacc_states_0 d a).
Definition dta_kill_non_coacc_lazy (d : DTA) : DTA :=
match d with
| dta p a => dta (predta_kill_non_coacc_lazy p a) a
end.
(* démo : un état apparait dans non_coacc_kill ssi il est coacc *)
(* coaccessibilité des états conservée en supprimant les coaccessibles *)
Definition predta_kill_non_coacc_def_0 (d : preDTA)
(a0 a1 : ad) : Prop :=
preDTA_ref_ok d ->
coacc d a0 a1 -> coacc (predta_kill_non_coacc d a0) a0 a1.
(* sémantique de reconnaissance dans les coaccessibles *)
(* sens trivial : si un terme est reconnu par l'automate où on a kille les non coaccessibles alors il est reconnu dans l automate *)
Definition predta_kill_non_coacc_rec_def_0 (p : preDTA)
(a : ad) (t : term) (pr : reconnaissance p a t) :=
forall (p0 : preDTA) (m : Map bool),
p = non_coacc_kill p0 m ->
ensemble_base state p0 m -> reconnaissance p0 a t.
Definition predta_kill_non_coacc_rec_def_1 (p : preDTA)
(s : state) (t : term) (pr : state_reconnait p s t) :=
forall (p0 : preDTA) (m : Map bool),
p = non_coacc_kill p0 m ->
ensemble_base state p0 m -> state_reconnait p0 s t.
Definition predta_kill_non_coacc_rec_def_2 (p : preDTA)
(pl : prec_list) (lt : term_list) (pr : liste_reconnait p pl lt) :=
forall (p0 : preDTA) (m : Map bool),
p = non_coacc_kill p0 m ->
ensemble_base state p0 m -> liste_reconnait p0 pl lt.
(* sens moins trivial : si un terme est reconnu par ... *)
Inductive reconnaissance_co : preDTA -> ad -> ad -> term -> Prop :=
rec_co_dta :
forall (d : preDTA) (a b : ad) (t : term) (ladj : state),
MapGet state d a = Some ladj ->
state_reconnait_co d ladj b t ->
coacc d b a -> reconnaissance_co d a b t
with state_reconnait_co : preDTA -> state -> ad -> term -> Prop :=
rec_co_st :
forall (d : preDTA) (s : state) (c b : ad) (tl : term_list)
(l : prec_list),
MapGet prec_list s c = Some l ->
liste_reconnait_co d l b tl -> state_reconnait_co d s b (app c tl)
with liste_reconnait_co : preDTA -> prec_list -> ad -> term_list -> Prop :=
| rec_co_empty :
forall (d : preDTA) (b : ad), liste_reconnait_co d prec_empty b tnil
| rec_co_consi :
forall (d : preDTA) (a : ad) (la ls : prec_list)
(hd : term) (b : ad) (tl : term_list),
reconnaissance_co d a b hd ->
liste_reconnait_co d la b tl ->
liste_reconnait_co d (prec_cons a la ls) b (tcons hd tl)
| rec_co_consn :
forall (d : preDTA) (a : ad) (la ls : prec_list)
(hd : term) (b : ad) (tl : term_list),
liste_reconnait_co d ls b (tcons hd tl) ->
liste_reconnait_co d (prec_cons a la ls) b (tcons hd tl).
Scheme mreconnaissance_co_ind := Induction for reconnaissance_co
Sort Prop
with mstrec_co_ind := Induction for state_reconnait_co
Sort Prop
with mlrec_co_ind := Induction for liste_reconnait_co
Sort Prop.
Definition rec_co_def_0 (d : preDTA) (a a1 : ad) (t : term)
(pr : reconnaissance_co d a a1 t) :=
forall a0 : ad, coacc d a0 a1 -> reconnaissance_co d a a0 t.
Definition rec_co_def_1 (d : preDTA) (s : state) (a1 : ad)
(t : term) (pr : state_reconnait_co d s a1 t) :=
forall a0 : ad, coacc d a0 a1 -> state_reconnait_co d s a0 t.
Definition rec_co_def_2 (d : preDTA) (p : prec_list)
(a1 : ad) (tl : term_list) (pr : liste_reconnait_co d p a1 tl) :=
forall a0 : ad, coacc d a0 a1 -> liste_reconnait_co d p a0 tl.

Lemma rec_co_3 :
forall (d : preDTA) (a : ad) (la ls : prec_list) (hd : term)
(b : ad) (tl : term_list) (r : reconnaissance_co d a b hd),
rec_co_def_0 d a b hd r ->
forall l : liste_reconnait_co d la b tl,
rec_co_def_2 d la b tl l ->
rec_co_def_2 d (prec_cons a la ls) b (tcons hd tl)
(rec_co_consi d a la ls hd b tl r l).