Inductive bar {X : Type} : list X -> Prop :=
| bar_nil : bar []
| bar_fst : forall x l, bar (rev l ++ l) -> bar (rev l ++ [x] ++ l)
| bar_snd : forall x l, bar (rev l ++ [x] ++ l) -> bar (rev l ++ [x; x] ++ l).
Axiom bar_surround :
forall X x (l : list X),
bar l -> bar ([x] ++ l ++ [x]).
Inductive list_last {X : Type} : list X -> Prop :=
| ll_nil : list_last []
| ll_snoc : forall l x, list_last l -> list_last (l ++ [x]).
Axiom ll_app :
forall X (a b : list X),
list_last a -> list_last b -> list_last (a ++ b).
Axiom ll_from_list :
forall {X} (l : list X),
list_last l.
Axiom app_head_eq :
forall X (a b c : list X),
a ++ c = b ++ c -> a = b.
Theorem foo :
forall X (l: list X), l = rev l -> bar l.
Proof.
intros.
induction l.
- constructor.
- assert (Hll := ll_from_list l).
inversion Hll.
+ apply (bar_fst x []). apply bar_nil.
+ rewrite <- H1 in H.
simpl in H.
rewrite rev_app_distr in H.
rewrite <- app_assoc in H.
simpl in H.
inversion H.
apply app_head_eq in H4.
apply bar_surround.
1 subgoal
X : Type
x : X
l, l0 : list X
x0 : X
H : x :: l0 ++ [x0] = x0 :: rev l0 ++ [x]
IHl : l = rev l -> bar l
Hll : list_last l
H0 : list_last l0
H1 : l0 ++ [x0] = l
H3 : x = x0
H4 : l0 = rev l0
______________________________________(1/1)
bar l0
Я только в шаге от решения этого упражнения, но я не знаю, как сделать вводный шаг. Обратите внимание, что IHl
здесь бесполезен, и замена индукции на l
на индукцию на Hll
приведет к аналогичной проблеме. В обоих случаях индуктивная гипотеза будет ожидать вызова с уменьшением на один шаг, а мне нужно два - один с элементом, взятым как из начала, так и из конца списка с обеих сторон равенства.
Учтите, что тип функции, которую я пытаюсь доказать, - forall X (l: list X), l = rev l -> bar l
, и у меня здесь l0 = rev l0 -> bar l0
в цели. l0
- уменьшенный аргумент, что делает рекурсивный вызов безопасным.
Что мне здесь делать?