Inductive list := nil | cons : nat -> list -> list.
Notation "x :: y" := (cons x y) (at level 60, right associativity).
Notation "[ x , .. , y ]" := (cons x .. (cons y nil) ..).
Fixpoint length xs := match xs with
| nil => 0
| x::xr => S(length xr)
end.
Fixpoint app xs ys := match xs with
| nil => ys
| x::xr => x::app xr ys
end.
Notation "x ++ y" := (app x y) (at level 60, right associativity).
Fixpoint rev xs:= match xs with
| nil => nil
| x::xr => rev xr ++ [x]
end.
Proposition P1: forall xs ys,
length(xs++ys) = length xs + length ys.
Proof. intros. induction xs.
trivial.
simpl. rewrite IHxs. trivial.
Qed.
Proposition P2: forall xs,
xs ++ nil = xs.
Proof. induction xs.
trivial.
simpl. rewrite IHxs. trivial.
Qed.
Proposition P3: forall xs ys zs,
xs++(ys++zs) = (xs++ys)++zs.
Proof. intros. induction xs.
trivial.
simpl. rewrite IHxs. trivial.
Qed.
Proposition P4: forall xs ys,
rev(xs++ys) = rev ys ++ rev xs.
Proof. intros. induction xs.
simpl. rewrite P2. trivial.
simpl. rewrite IHxs. rewrite P3. trivial.
Qed.
Proposition P5 : forall xs,
rev (rev xs) = xs.
Proof. induction xs.
trivial.
simpl. rewrite P4. rewrite IHxs. trivial.
Qed.