2016-08-02 80 views
0

在我的理論中,我有一些更大的定義,從中我使用引理推導出一些簡單的屬性。條件重寫規則與未知條件

我的問題是,用於派生屬性的引理沒有被簡化器使用,我必須手動實例化它們。有沒有辦法讓這個更自動化?

的最小例子如下所示:

definition complexFact :: "int ⇒ int ⇒ int ⇒ bool" where 
"complexFact x y z ≡ x = y + z" 

lemma useComplexFact: "complexFact x y z ⟹ x = y + z" 
by (simp add: complexFact_def) 

lemma example_1: 
assumes cf: "complexFact a b c" 
shows "a = b + c" 
apply (simp add: cf useComplexFact) (* easy, works *) 
done 

lemma example_2a: 
assumes cf: "complexFact a b c" 
shows "a - b = c" 
apply (simp add: cf useComplexFact) (* does not work *) 
oops 

lemma example_2b: 
assumes cf: "complexFact a b c" 
shows "a - b = c" 
apply (simp add: useComplexFact[OF cf]) (* works *) 
done 

lemma example_2c: 
assumes cf: "complexFact a b c" 
shows "a - b = c" 
apply (subst useComplexFact) (* manually it also works*) 
apply (subst cf) 
apply simp+ 
done 

我發現在參考手冊中的下段,所以我想我可以解決我的問題與自定義解算器。 但是,我從來沒有真正觸及伊莎貝爾的內部ML部分,也不知道從哪裏開始。

重寫不實例化未知數。例如,單獨重寫 不能證明是一個ε?A,因爲這需要實例化?A。然而,求解器是一種隨意的策略,可以根據需要實例化未知數 。這是Simplifier處理 條件包含額外變量的條件重寫規則的唯一方法。

回答

3

Isabelle簡化器本身從不會在條件重寫規則的假設中實例化未知數。然而,求解器可以做到這一點,最可靠的是assumption。因此,如果complex_fact a b c字面上出現在目標的假設中(而不是被添加到simpset中simp add:[simp]),則假設求解器會啓動並實例化未知量。但是,它只會在假設中使用complex_fact的第一個實例。所以如果有幾個,它不會嘗試所有這些。總之,最好是寫

lemma 
    assumes cf: "complexFact a b c" 
    shows "a = b + c" 
    using cf 
    apply(simp add: useComplexFact) 

與示例中的第二個問題是a = b + cabc是免費不是一個好重寫規則,因爲在左側頭部符號不是一個常數,而是自由變量a。因此,簡化器將不會使用方程a = b + c來替換ab + c,而是用方程a = b + c的文字出現替換爲True。您可以在簡化器的蹤跡中看到這個預處理(使用using [[simp_trace]]在本地啓用它)。這就是爲什麼example_1工作,其他人不工作的原因。如果你可以改變你的左手邊,使得頭部符號有一個常數,那麼在不寫一個自定義求解器的情況下,應該有一些體面的自動化證明。

此外,您可以使用useComplexFact作爲銷燬規則,進行一些(有限)形式的轉發推理。也就是,

using assms 
apply(auto dest!: useComplexFact) 

也可以在某些情況下工作。然而,這與在可伸縮性方面展開定義非常接近。

+0

謝謝。爲什麼假設求解器在下面的例子2中不起作用:'使用cf apply(simp add:useComplexFact [where x = a])''。我使左側不變,simp_trace顯示'[0]添加重寫規則「??。unknown」: complexFact a?y1?z1?a??y1 +?z1'。然而,假設求解器沒有實例化未知數? – peq

+1

'simp add:useComplexFact [where x = a]'不起作用,所得到的重寫規則是'complexFact a?y?z ==> a =?y +?z'。所以當簡化器看到一個'a'並試圖在其上使用這個規則時,它必須解決'complexFact a?y?z'的條件。由於簡化器在任何解算器之前首先調用它自己,它試圖處理這個條件,並且它包含一個'a'。因此它會嘗試再次使用相同的條件重寫規則,直到達到簡化深度限制並且簡化器中止整個條件重寫鏈(在簡化器中沒有回溯)。 –

-1

您可以在定義中指定,它應該在前面加上[simp]:這樣的自動輸送到簡化器:

definition complexFact :: "int ⇒ int ⇒ int ⇒ bool" where 
[simp]: "complexFact x y z ≡ x = y + z" 

現在所有的例子引理應該是可以解決的直接using cf by simp

+1

添加'[SIMP]'來定義失敗的定義的目的,因爲它會被簡化器始終展開。所以抽象沒有任何好處。它可能適用於這個例子中的小規模定義,但不能縮放。 –

+0

你是對的,不應該使用[定義]與[定義]。我顯然誤解了這個問題。我認爲這是關於如何在全球範圍內增加一些東西給簡單集合,因爲「我的問題是,導出屬性的引理不被簡化器使用......」這句話,但是另一方面它是關於引理不是即使他們在簡體中使用。 –