RIS.traces: extracting stacks directly from words.

Set Implicit Arguments.

Require Export transducer.

Section s.
  Context {atom X: Set}{๐€ : Atom atom} {๐— : Alphabet ๐€ X}.

Simple trace

We introduce here the notion of trace of a word. Intuitively, the trace of a word u is a list of names, corresponding to the unmatched โŸจa appearing in u. They appear in reverse order, for instance the trace of [โŸจa;โŸจb] will be [b;a].
The trace of a word u after a trace l is computed by the following reverse inductive definition:
  • Tr l [] = l;
  • Tr l (u++[โŸจa])=a::Tr l u;
  • Tr l (u++[var x])=Tr l u;
  • Tr l (u++[aโŸฉ])=(Tr l u) โŠ– a.
Definition updTr acc l :=
  match l with
  | var _ โ‡’ acc
  | โŸจa โ‡’ a::acc
  | aโŸฉ โ‡’ acc โŠ– a
  end.
Definition Tr l u := fold_left updTr u l.

The following identities hold.
Lemma Tr_app l u v : Tr l (u++v) = Tr (Tr l u) v.
Lemma Tr_add l u a : Tr l (u++[a]) = updTr (Tr l u) a.

This technical lemma will be used for the next proposition.
The number of occurrences of a in Tr l u can be obtained from the number of as in l by first subtracting d_binding (๐—™ a u), and then adding c_binding (๐—™ a u).
Proposition Tr_length_binding_atom a l u :
  nb a (Tr l u) = (nb a l - d_binding (๐—™ a u)) + c_binding (๐—™ a u).

The atoms in the trace Tr l u all appear either in the support of u or in l.
If a does not appear in Tr l u (for any l), then a is close-balanced in u.
If a is close-balanced in u, then it cannot appear in Tr [] u. Note however that it could appear in Tr l u for some l: take for instance l=[a] and u=[].
Tr commutes with the action of permutations.
Lemma Tr_perm p u l : pโˆ™(Tr l u) = Tr (pโˆ™l) (pโˆ™u).

Indexed traces

For Theorem path_ฮฑequiv, we will need a stronger notion of traces. Simple traces, as defined in the previous section, list the occurrences of unmatched โŸจa. In the definition to come we strengthen this by adding a natural number corresponding to the index of the letter in u where the unmatched โŸจa was found.

Technical definition

We start by defining a variant of rmfst, intended to work on lists of pairs built out of a number an an atom. Its effect will be made clear by the following lemmas.
Fixpoint rmfstn (a : atom) (l : list (natร—atom)) :=
  match l with
  | [] โ‡’ []
  | (n,b)::l โ‡’ if a=?=b then l else (n,b)::(rmfstn a l)
  end.

Given a name a and a list l, if there is no pair of the shape (n,a) in l then rmfstn a l = l.
If on the other hand there are such pairs in l, then rmfstn a l will remove from l the first of them.
Lemma rmfstn_in a n l1 l2 :
  ยฌ a โˆˆ prj2 l1 โ†’ rmfstn a (l1 ++ (n,a) :: l2) = l1++l2.

rmfst and rmfstn are related by the following identity.
rmfstn a l is contained in the list l.
Lemma rmfstn_decr a l : rmfstn a l โŠ† l.

Main definitions

We define Trn as follows. Its meaning will become clearer with the following lemmas.
Definition updTrn (accn : nat ร— list (nat ร— atom)) l :=
  let n := fst accn in
  let acc := snd accn in
  match l with
  | var _ โ‡’ (S n,acc)
  | โŸจa โ‡’ (S n,(n,a)::acc)
  | aโŸฉ โ‡’ (S n,rmfstn a acc)
  end.
Definition Trn_aux l u := fold_left updTrn u l.
Definition Trn u := snd (Trn_aux (0,[]) u).

Properties of indexed traces

The second projection of Trn u is Tr [] u.
Remark updTrn_updTr acc l :
  prj2 (snd (updTrn acc l)) = updTr (prj2 (snd acc)) l.

Corollary Trn_Tr u : prj2 (Trn u) = Tr [] u.

Any number appearing in the first projection of Trn u is strictly smaller than the length of u.
If the pair (n,a) appears in Trn u, then the letter at index n in u is โŸจa.
If the number n1 appears before n2 in Trn u, then n2<n1.
Lemma Trn_incr u n1 a1 n2 a2 u1 u2 u3 :
  Trn u = u1++(n1,a1)::u2++(n2,a2)::u3 โ†’ n2 < n1.

To state results about the binding power, we define the boolean predicate select n a. It holds for pairs (m,b) where nโ‰คm and a=b.
Definition select n (a : atom) p := Nat.leb n (fst p) && a =?= (snd p).
Lemma select_spec n a m b : select n a (m,b) = true โ†” n โ‰ค m โˆง a = b.

The number of pairs (n,a), such that n is smaller than or equal to the length of u, appearing in Trn (u++v) is equal to c_binding (๐—™ a v).
If the pair (โŽขuโŽฅ,a) appears in Trn (u++โŸจa::v), then a is close-balanced in v.

Correspondence with stacks

If there is a path labelled with u|v from s1 to s2, then the first component of s2 is the trace of u after the first component of s1.
Lemma Tr_step a b s1 s2 : s1 โŠฃ a | b โ†ฆ s2 โ†’ prj1 s2 = updTr (prj1 s1) a.
Corollary Tr_path u v s1 s2 : s1 โŠฃ u | v โค… s2 โ†’ prj1 s2 = Tr (prj1 s1) u.
Corollary Trn_path_snd u v s2 :
  [] โŠฃ u | v โค… s2 โ†’ prj1 s2 = prj2 (Trn u).
One can also understand that property as stating that if there is a path labelled with u|v from the empty stack to s, then s must be the combination of the trace of u with the trace of v.
If there is a path labelled with u|v from the empty stack to s, then the first projections of the indexed traces of u and v coincide.
Proposition Trn_path_fst u v s :
  [] โŠฃ u | v โค… s โ†’ prj1 (Trn u) = prj1 (Trn v).

End s.