Как вы заметили во время попытки доказательства, при вводе шага индукции от rev_append l [x]
до rev_append (h :: t) [x]
вы получаете термин rev_append t [h; x]
после упрощения. Шаг индукции ведет не к базовому случаю функции rev_append
, а к другому рекурсивному вызову, который нельзя упростить.
Обратите внимание, как гипотеза индукции, которую вы хотели бы применить, делает утверждение о rev_append t [x]
для некоторого фиксированного x
, но в вашей цели дополнительный элемент списка h
перед тем, как он встанет на пути, и гипотеза индукции бесполезна.
Это то, на что имел в виду ответ Бабблера, когда утверждал, что ваша гипотеза индукции недостаточно сильна: он делает заявление только о случае, когда второй аргумент является списком с единственным элементом. Но даже после шага индукции (одно рекурсивное приложение) в этом списке уже есть как минимум два элемента!
Как предположил Баблер, вспомогательная лемма rev_append l (l1 ++ l2) = rev_append l l1 ++ l2
сильнее и не имеет этой проблемы: при использовании в качестве гипотезы индукции ее также можно применить к rev_append t [h; x]
, что позволяет вам доказать равенство с rev_append t [h] ++ [x]
.
Пытаясь доказать вспомогательную лемму, вы можете застрять (как и я) точно так же, как и при доказательстве самого rev_append_app
. Важнейший совет, который помог мне продолжить, заключался в том, чтобы быть осторожным с тем, какие из универсально количественно определяемых переменных вы вводите, прежде чем начинать индукцию. Если вы специализируетесь на каком-либо из них слишком рано, вы можете ослабить свою гипотезу индукции и снова застрять. Возможно, вам придется изменить порядок этих количественных переменных или использовать тактику generalize dependent
(см. Тактика главы Основы логики).
person
Simon
schedule
07.08.2019