Может быть целесообразно использовать listrel
вместо list_all2
.Действительно, как показано ниже, они эквивалентны (см. set_listrel_eq_list_all2
).Однако в стандартной библиотеке есть несколько теорем о listrel
, у которых нет эквивалентов для list_all2
.
theory so_htlatrfetl_2
imports Complex_Main
begin
lemma set_listrel_eq_list_all2:
"listrel {(x, y). r x y} = {(xs, ys). list_all2 r xs ys}"
using list_all2_conv_all_nth listrel_iff_nth by fastforce
lemma listrel_tclosure_1: "(listrel r)⇧* ⊆ listrel (r⇧*)"
by (simp add: listrel_rtrancl_eq_rtrancl_listrel1
listrel_subset_rtrancl_listrel1 rtrancl_subset_rtrancl)
lemma listrel_tclosure_2: "refl r ⟹ listrel (r⇧*) ⊆ (listrel r)⇧*"
by (simp add: listrel1_subset_listrel listrel_rtrancl_eq_rtrancl_listrel1
rtrancl_mono)
context includes lifting_syntax
begin
lemma listrel_list_all2_transfer [transfer_rule]:
"((=) ===> (=) ===> (=) ===> (=))
(λr xs ys. (xs, ys) ∈ listrel {(x, y). r x y}) list_all2"
unfolding rel_fun_def using set_listrel_eq_list_all2 listrel_iff_nth by blast
end
lemma list_all2_rtrancl_1:
"(list_all2 r)⇧*⇧* xs ys ⟹ list_all2 r⇧*⇧* xs ys"
proof(transfer)
fix r :: "'a ⇒ 'a ⇒ bool"
fix xs :: "'a list"
fix ys:: "'a list"
assume "(λxs ys. (xs, ys) ∈ listrel {(x, y). r x y})⇧*⇧* xs ys"
then have "(xs, ys) ∈ (listrel {(x, y). r x y})⇧*"
unfolding rtranclp_def rtrancl_def by auto
then have "(xs, ys) ∈ listrel ({(x, y). r x y}⇧*)"
using listrel_tclosure_1 by auto
then show "(xs, ys) ∈ listrel {(x, y). r⇧*⇧* x y}"
unfolding rtranclp_def rtrancl_def by auto
qed
lemma list_all2_rtrancl_2:
"reflp r ⟹ list_all2 r⇧*⇧* xs ys ⟹ (list_all2 r)⇧*⇧* xs ys"
proof(transfer)
fix r :: "'a ⇒ 'a ⇒ bool"
fix xs :: "'a list"
fix ys :: "'a list"
assume as_reflp: "reflp r"
assume p_in_lr: "(xs, ys) ∈ listrel {(x, y). r⇧*⇧* x y}"
from as_reflp have refl: "refl {(x, y). r x y}"
using reflp_refl_eq by fastforce
from p_in_lr have "(xs, ys) ∈ listrel ({(x, y). r x y}⇧*)"
unfolding rtranclp_def rtrancl_def by auto
with refl have "(xs, ys) ∈ (listrel {(x, y). r x y})⇧*"
using listrel_tclosure_2 by auto
then show "(λxs ys. (xs, ys) ∈ listrel {(x, y). r x y})⇧*⇧* xs ys"
unfolding rtranclp_def rtrancl_def by auto
qed
end
Также предоставляется прямое доказательство для list_all2
(наследие):
list_all2_induct
применяется к спискам;базовый случай тривиален.Отсюда осталось показать, что (L P)* x#xs y#ys
, если (L (P*)) xs ys
, (L P)* xs ys
и P* x y
. - Идея состоит в том, что можно найти
zs
(например, xs
) такой, что (L P) xs zs
и (L P)+ zs ys
. - Затем, учитывая, что
P* x y
и P x x
, по индукции на основе переходных свойств P*
, (L P) x#xs y#zs
.Следовательно, также, (L P)* x#xs y#zs
. - Кроме того, учитывая, что
(L P)+ zs ys
и P y y
, по индукции (L P)+ y#zs y#ys
.Таким образом, также, (L P)* y#zs y#ys
. - Из 3 и 4 заключаются
(L P)* x#xs y#ys
.
theory so_htlatrfetl
imports Complex_Main
begin
lemma list_all2_rtrancl2:
assumes as_r: "(⋀x. P x x)"
shows "(list_all2 P⇧*⇧*) xs ys ⟹ (list_all2 P)⇧*⇧* xs ys"
proof(induction rule: list_all2_induct)
case Nil then show ?case by simp
next
case (Cons x xs y ys) show ?case
proof -
from as_r have lp_xs_xs: "list_all2 P xs xs" by (rule list_all2_refl)
from Cons.hyps(1) have x_xs_y_zs: "(list_all2 P)⇧*⇧* (x#xs) (y#xs)"
proof(induction rule: rtranclp_induct)
case base then show ?case by simp
next
case (step y z) then show ?case
proof -
have rt_step_2: "(list_all2 P)⇧*⇧* (y#xs) (z#xs)"
by (rule r_into_rtranclp, rule list_all2_Cons[THEN iffD2])
(simp add: step.hyps(2) lp_xs_xs)
from step.IH rt_step_2 show ?thesis by (rule rtranclp_trans)
qed
qed
from Cons.IH have "(list_all2 P)⇧*⇧* (y#xs) (y#ys)"
proof(induction rule: rtranclp_induct)
case base then show ?case by simp
next
case (step ya za) show ?case
proof -
have rt_step_2: "(list_all2 P)⇧*⇧* (y#ya) (y#za)"
by (rule r_into_rtranclp, rule list_all2_Cons[THEN iffD2])
(simp add: step.hyps(2) as_r)
from step.IH rt_step_2 show ?thesis by (rule rtranclp_trans)
qed
qed
with x_xs_y_zs show ?thesis by simp
qed
qed
end
Как примечание стороны, на мой взгляд (Я очень мало знаю о Нитпике), Нитпик не должен предоставлять недействительные контрпримеры без какого-либо предупреждения.Обычно я полагаю, что когда nitpick
«подозревает», что контрпример может быть недействительным, он уведомляет пользователя о том, что этот пример «потенциально фальшивый».Может быть полезно отправить отчет об ошибке, если эта проблема не была зарегистрирована в другом месте.