Library prefix


Defines the prefix property on lists and establishes general results about it.

Require Export List. Export ListNotations.
Require Export prog.
Require Import seq.

Inductive prefix {A} : list A list A Prop :=
  | PR_nil : l, prefix [] l
  | PR_after : l1 l2 x, prefix l1 l2 prefix (x::l1) (x::l2).

Lemma prefix_refl : A (l:list A),
  prefix l l.
Proof.
  intros. induction l. apply PR_nil.
  apply PR_after. exact IHl.
Qed.

Lemma prefix_irrefl : A (l1 l2:list A),
  prefix l1 l2 prefix l2 l1 l1 = l2.
Proof.
  intros.
  induction H as [l | l1' l2' x]. inversion H0. reflexivity.
  inversion H0. rewrite IHprefix. reflexivity. assumption.
Qed.

Lemma prefix_trans : A (l1 l2 l3:list A),
  prefix l1 l2 prefix l2 l3 prefix l1 l3.
Proof.
  intros. revert l1 H.
  induction H0; intros.
  - inversion H. apply PR_nil.
  - inversion H. apply PR_nil. apply PR_after. apply IHprefix; assumption.
Qed.

Lemma prefix_length : {A} (l1 l2 : list A),
  prefix l1 l2 length l1 length l2.
Proof.
  intros. induction H.
  - apply le_0_n.
  - simpl. apply le_n_S. assumption.
Qed.

Lemma prefix_single : A x (l1 l2 : list A),
  prefix (x::l1) (x::l2) prefix l1 l2.
Proof.
  split; intros.
  - inversion H. assumption.
  - apply PR_after. assumption.
Qed.

Inductive prefix_prog : prog prog Prop :=
  | PP_nil : p, prefix_prog {{}} p
  | PP_after : p1 p2 s, prefix_prog p1 p2 prefix_prog (s;;p1) (s;;p2).

Lemma prefix_prog_refl : p,
  prefix_prog p p.
Proof.
  intros. induction p. apply PP_nil.
  apply PP_after. exact IHp.
Qed.

Lemma prefix_prog_irrefl : p1 p2,
  prefix_prog p1 p2 prefix_prog p2 p1 p1 = p2.
Proof.
  intros.
  induction H as [p | p1' p2' s]. inversion H0. reflexivity.
  inversion H0. rewrite IHprefix_prog. reflexivity. assumption.
Qed.

Lemma prefix_prog_trans : p1 p2 p3,
  prefix_prog p1 p2 prefix_prog p2 p3 prefix_prog p1 p3.
Proof.
  intros. revert p1 H.
  induction H0; intros.
  - inversion H. apply PP_nil.
  - inversion H. apply PP_nil. apply PP_after. apply IHprefix_prog; assumption.
Qed.

Lemma prefix_prog_single : p1 p2 s,
  prefix_prog (s;;p1) (s;;p2) prefix_prog p1 p2.
Proof.
  split; intros.
  - inversion H. assumption.
  - apply PP_after. assumption.
Qed.

Lemma prefix_prog_app : p q,
  prefix_prog p (p+;+q).
Proof.
  intros. induction p.
  - apply PP_nil.
  - simpl. apply PP_after. assumption.
Qed.

Lemma prefix_prog_intro : p q,
  prefix_prog p q r, q = p +;+ r.
Proof.
  split; intros.
  - induction H.
    + p. reflexivity.
    + inversion IHprefix_prog as [r H0].
       r. simpl. rewrite <- H0. reflexivity.
  - inversion H as [r H0]. rewrite H0. apply prefix_prog_app.
Qed.