I defined a type of s-expressions and it's printing functions.
Inductive sexp : Set :=
K : string -> (list sexp) -> sexp
.
Fixpoint sexpprint (s:sexp) : list string :=
match s with
K n l => ["("%string]++[n]++(concat (map sexpprint l))++[")"%string]
end.
(Yes, I understand it can be just string, not the list of strings, but Coq have small amount of theorems for working with strings, but a big amount for working with lists.)
(* more usual function
Fixpoint sexpprint (s:sexp) :string :=
match s with
K n l => ("(":string)++n++(String.concat "" (map sexpprint l))++")"
end.
*)
And I've got stuck trying to prove this theorem:
Theorem sexpprint_inj s1 s2:
sexpprint s1 = sexpprint s2 -> s1 = s2.
Maybe there are some sources which can help me to plan the theorem's proof? (books/articles/codes) How to prove it? (Maybe I need a special kind of inductive principle, could you formulate its statement?)
Also I defined depth function, it may somehow help
Fixpoint depth (s:sexp) : nat :=
match s with
K n l =>
(match l with
nil => 0
| _ => S (list_max (map depth l))
end)
end.
Thanks!
p.s. some additional thoughts:
Theorem depth_decr n l s m:
depth (K n l) = m
->
In s l
->
depth s < m
.
Proof.
Admitted.
Theorem step_lem (m:nat) :
(forall s1 s2,
depth s1 < m ->
depth s2 < m ->
sexpprint s1 = sexpprint s2 -> s1 = s2
) ->
(forall s1 s2,
depth s1 = m ->
depth s2 = m ->
sexpprint s1 = sexpprint s2 -> s1 = s2
).
Proof.
intros H s1 s2 Q1 Q2 E.
destruct s1 as [n1 l1], s2 as [n2 l2].
simpl in E.
inversion E as [E1].
apply (app_inv_tail) in H0.
Search "concat".
cut (l1=l2).
intros []; reflexivity.
Search "In".
induction l1, l2.
+ trivial.
+ simpl in H0.
destruct s.
unfold sexpprint in H0.
simpl in H0.
inversion H0.
+ simpl in H0.
destruct a.
unfold sexpprint in H0.
simpl in H0.
inversion H0.
+ admit.
Admitted.
p.p.s. I feel like the main obstacle is performing induction on two lists.