2013-03-08 4 views
6

Иногда, когда я пишу доказательства применить стиле, я хотел способ модифицировать метод доказательства foo кПрименить метод, если и только если он решает текущую задачу

Попробуйте foo на первый Цель. Если он решает цель, хорошо; если он не решает его, вернитесь в исходное состояние и не получится.

Это произошло в следующем коде:

qed (subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)+ 

После некоторого изменения дальше, вызов simp не будет в полной мере решить задачу больше, и тогда это будет цикл. Если бы я мог указано что-то вроде

qed (solve_goal(subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail))+ 

или (альтернативный вариант предложил synatx)

qed ((subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)!)+ 

или (может быть, даже лучше, синтаксис)

qed ((subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)[1!])+ 

он остановился бы на первый гол, не был разрешен этим сценарием.

+0

Я предполагаю, что ваш 'fibs.simps' или' fib.simps' вызвать зацикливание поведения (возможно, из-за общую левую сторону, и если на Правая сторона)? Часто их можно заменить условными правилами. –

+0

Я отправил [исправление, реализующее это] (https://mailmanbroy.informatik.tu-muenchen.de/pipermail/isabelle-dev/2013-March/003911.html), давайте посмотрим, что произойдет. –

+0

@Joachim Breitner: Только для записи лично я не думаю, что в структурированном доказательстве (как ваш пример) такое чудовище принадлежит 'qed' ;;). Я всегда предпочел бы явно установить еще один под-доказательство в соответствующем 'proof' /' qed'. Однако вы говорите о скриптах «apply», и для них я полностью согласен. (Может быть, вы могли бы превратить 'qed' в ваш пример в' apply'?) – chris

ответ

3

С появлением Eisbach proof script language, это теперь поддерживается , После импорта "~~/src/HOL/Eisbach/Eisbach", можно заменить

apply foo 

с

apply (solves ‹foo›) 

и линия потерпит неудачу, если solves производит какие-либо новые цели. Это может быть объединен с [1], как в

apply (solves ‹(auto)[1]›) 

при желании.

Определение solves на самом деле довольно просто:

method solves methods m = (m; fail) 
3

Изабель не имеет такого комбинатора, который тоже я пропустил. Часто я могу избежать необходимости в таком комбинаторе, если я заменил auto или simp звонки на fastforce или force (которые имеют поведение с ошибкой или неудачей).

Таким образом, если simp в вашем примере предполагается решить задачу (без зацикливания),

qed (subst fibs.simps, (subst fib.simps)?, fastforce simp: nth_zipWith nth_tail)+ 

может быть более надежным вариантом.

+1

Ах, наконец, причина использовать 'fastforce' или' force' - я никогда не чувствовал необходимости в них и использовал только 'auto' и' simp'. Тем не менее, можно ли реализовать такой комбинатор с 'ML {* .. *}' или эта часть не расширяема? –

+2

Подъязык метода Isabelle/Isar может быть расширен с помощью 'method_setup', но некоторые комбинаторы методов фиксированы. Таким образом, вы можете определить свой собственный метод доказательства, основанный на произвольной сложной тактике и тактике, но это не изменит стилизованные формы выражений метода доказательства. – Makarius

0

Язык Isar Isabelle не предусматривает эту функцию; это намеренное и не ошибка, как объяснено on the isabelle developer list:

Изар язык доказательства метод был разработан определенный путь, чтобы прибыть в «stilized» характеристики некоторых оперативных аспектов в доказательство текста. Он исключил любые виды программирования или сложного управления объектами .

1

Хотя нет встроенной тактики или комбинатора доступны, вы можете реализовать его самостоятельно следующий образом:

ML {* 
fun solved_tac thm = 
    if nprems_of thm = 0 then Seq.single thm else Seq.empty 
*} 

method_setup solved = {* 
    Scan.succeed (K (SIMPLE_METHOD solved_tac)) 
*} 

Это создает новый метод solved, который будет успешным, если текущая цель была полностью решена , или сбой, если осталось еще одно или несколько подцелей.

Он может быть использован, например, следующим образом:

lemma "a ∨ ¬ a " 
    apply ((rule disjI1, solved) | (simp, solved)) 
    done 

Без пункта solved, Isabelle отберет rule disjI1 сторону apply шага, оставив вас с неразрешимой целью.С предложением solved в каждой стороне Изабель пытается использовать rule disjI1 и, когда он не может решить цель, переключается на simp, который затем успешно завершен.

Это может использоваться, чтобы решить индивидуальные цели, используя синтаксис Isabelle's (...)[1]. Например, следующий оператор будет пытаться решить столько подцели, как это возможно с помощью simp, но оставит подцель неизменным, если simp не сможет полностью решить:

apply ((simp, solved)[1])+ 
+0

Отлично, это позволяет мне иметь желаемый 'метод [1!]' (Который преуспевает, если 'метод' решает первую цель, даже если есть другие цели) как' (метод, решено) [1] '. –

+0

Я думаю, что я также начал где-то похожий код, который даст метод 'assert_goals n', который будет успешным, если число открытых целей будет n ... –

+0

@JoachimBreitner: Спасибо. Я хотел это упомянуть, но это сошло с ума. Я добавил пример в конце, который, надеюсь, поможет будущим искателям. – davidg