I am trying to prove the following theorem by induction over l. It's an easy theorem on paper, however when I try to prove it in Coq I am not getting the induction goal I would expect.
Theorem nodup_app__disjoint: forall {X: Type} (l: list X),
(forall l1 l2 : list X, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l.
Proof.
intros X l. induction l.
- intros F. apply nodup_nil.
- (* ??? *)
The state at this point:
1 subgoal
X : Type
x : X
l : list X
IHl : (forall l1 l2 : list X, l = l1 ++ l2 -> Disjoint l1 l2) -> NoDup l
______________________________________(1/1)
(forall l1 l2 : list X, x :: l = l1 ++ l2 -> Disjoint l1 l2) ->
NoDup (x :: l)
But that is not at all the goal I would expect! Shouldn't x :: l = l1 ++ l2
be replaced by l = l1 ++ l2
?
Here are the propositions I'm working with, in case you'd like to reproduce the problem and see for yourself:
Inductive Disjoint {X : Type}: list X -> list X -> Prop :=
| disjoint_nil: Disjoint [] []
| disjoint_left: forall x l1 l2, Disjoint l1 l2 -> ~(In x l2) -> Disjoint (x :: l1) l2
| disjoint_right: forall x l1 l2, Disjoint l1 l2 -> ~(In x l1) -> Disjoint l1 (x :: l2).
Inductive NoDup {X: Type}: list X -> Prop :=
| nodup_nil: NoDup []
| nodup_cons: forall hd tl, NoDup tl -> ~(In hd tl) -> NoDup (hd :: tl).