Я даю вам доказательства и объясню некоторые основные методы, которые я использовал для получения результатов, но довольно бессмысленным способом. Кто-то может пожелать дать объяснение, которое даст вам лучшее представление о предмете: индукция с участием nat
и list
.
Я укоротил некоторые идентификаторы, и я поставил всю теорию ниже. Существуют в основном две свободные переменные, которые находятся в формулах, которые нуждаются в доказательствах: ls
и idx
.
Таким образом, для целей доказательства, пытаясь вещи, я делаю много того, что я покажу дальше, или некоторые вариации, с возможно cases
для induct
:
(*MINDLESS_TECHNIQUE_1*)
apply(induct ls, auto)
apply(induct idx, auto)
В определенный момент, auto
принимает долгое время, а это означало, что было возможно зацикливанием плохо из-за simp
правил, которые вы имели в.
я устранил simp
правил и вставил их только там, где это необходимо, которая избавилась от auto
обхвата.
Это был первый прорыв, который довел меня до MINDLESS_TECHNIQUE_2, вырвав доказательство в lemma
, который будет использоваться с MINDLESS_TECHNIQUE_1 вместе с Sledgehammer.
На данный момент, для вашего modification_lemma
, после использования apply
, как и выше, у меня было 3 доказательств, и я использовал Sledgehammer, чтобы доказать, что они двое. Затем я выбил 3-й доказательный гол, как показано ниже, что было легко доказано с помощью by(induct ls, auto)
.
Обновление: Использование наконечника Александра для достижения той же цели проверки, что и вышеизложенная лемма, я добавил доказательство в источнике ниже, где я разворачиваю две связанные переменные. Это по-прежнему уродливое решение, поэтому, возможно, есть лучший способ, чем связать переменные.
Использование auto
или simp_all
как я, поэтому я не могу бездумно получить окончательный результат с by(induct ls, auto)
потому, что переменные idx
и ls
связаны мета-всех, !!
. Они должны быть развернуты, если ни один автоинструмент не сможет выполнить пробную работу (я думаю), которая много мешает.
theory c2
imports Main Option String
begin
fun list_diff :: "string list => string list => nat" where
"list_diff [] [] = 0"
|"list_diff [] x = length x"
|"list_diff x [] = length x"
|"list_diff (x#d1) (y#d2) =
(if (x=y) then list_diff d1 d2 else (1 + list_diff d1 d2))"
fun modify :: "string list => nat => string list" where
"modify ls n = ls[n := ''abc'']"
lemma diff_zero:
"list_diff ls ls = 0"
by(induct_tac ls, auto)
lemma sub1:
"modify [] 0 = []"
by(auto)
lemma diff_zero_basecase:
"list_diff ls (modify ls 0) <= 1"
by(induct_tac ls, auto simp add: diff_zero)
(*****************************************************************************)
lemma the_mindless_result_of_eliminating_simp_rules_and_breaking_out_goals:
"(!!a ls. list_diff ls (ls[idx := ''abc'']) <= Suc 0 ==>
list_diff (a # ls)
(case idx of 0 => ''abc'' # ls | Suc j => a # ls[j := ''abc'']) <= Suc 0)
==> list_diff ls (ls[Suc idx := ''abc'']) <= Suc 0 ==>
list_diff ls (ls[idx := ''abc'']) <= Suc 0"
by(induct ls, auto)
lemma modification_lemma:
"list_diff ls (modify ls idx) <= 1"
apply(induct ls, auto)
apply(induct idx, auto)
apply(metis diff_zero le0)
apply(metis diff_zero) (*The goal I broke out to the above lemma.*)
by (metis the_mindless_result_of_eliminating_simp_rules_and_breaking_out_goals)
(*****************************************************************************)
(*Update: After the third 'apply', I can't mindlessly do 'by(induct ls, auto)',
because variables 'ls' and 'idx' are bound by '!!. If I use 'auto' like I
did, and I don't want to break out the proof goal, I need to unwrap the
variables 'idx' and 'ls, as shown below.*)
lemma unwrapping_variables:
"list_diff ls (modify ls idx) <= 1"
apply(induct ls, simp_all)
apply(induct idx, simp_all)
apply(simp_all add: diff_zero)
proof-
fix idx
show "!!ls. ((!!a ls. list_diff ls (ls[idx := ''abc'']) <= Suc 0 ==>
list_diff (a # ls)
(case idx of 0 => ''abc'' # ls | Suc j => a # ls[j := ''abc'']) <= Suc 0)
==> list_diff ls (ls[Suc idx := ''abc'']) <= Suc 0 ==>
list_diff ls (ls[idx := ''abc'']) <= Suc 0)"
proof-
fix ls
show "(!!a ls. list_diff ls (ls[idx := ''abc'']) <= Suc 0 ==>
list_diff (a # ls)
(case idx of 0 => ''abc'' # ls | Suc j => a # ls[j := ''abc'']) <= Suc 0)
==> list_diff ls (ls[Suc idx := ''abc'']) <= Suc 0 ==>
list_diff ls (ls[idx := ''abc'']) <= Suc 0"
by(induct ls, auto)
qed
qed
thm unwrapping_variables
end
Последние строки с 'metis' может быть заменена на' применяется (simp_all добавить: diff_zero) на (правило the_mindless_result_of_eliminating_simp_rules_and_breaking_out_goals) simp_all'. –
@ Александр, ладно, это хорошо. –