有沒有辦法比較兩個函數的相等性?例如,(λx.2*x) == (λx.x+x)
應該返回true,因爲這些顯然是等價的。如何比較兩個函數的等價性,如(λx.2* x)==(λx.x+ x)?
回答
這幾乎衆所周知,一般功能平等是一般不可判定的,所以你必須選擇那些你感興趣的問題的一個子集,你可能會考慮一些局部的解決方案:
- Presburger arithmetic是一階邏輯+算術的可判定片段。
- universe包爲有限域的全部函數提供功能相等測試。
- 您可以檢查您的函數在大量輸入上是否相等,並將其視爲未測試輸入上的相等證據;退房QuickCheck。
- SMT求解器盡最大努力,有時會回答「不知道」而不是「相等」或「不相等」。在Hackage上對SMT解決方案有幾種綁定;我沒有足夠的經驗來推薦最好的,但Thomas M. DuBuisson建議sbv。
- 在緊湊函數上決定函數相等和其他事情的研究有趣;該研究的基礎知識在博客文章Seemingly impossible functional programs中進行了描述。 (請注意,緊湊是一個非常強大和非常微妙的條件!它不是大多數Haskell函數都能滿足的。)
- 如果您知道函數是線性的,則可以找到源空間的基礎;那麼每個函數都有一個獨特的矩陣表示。
- 您可以嘗試定義自己的表達式語言,證明等效性對於此語言是可決定的,然後將該語言嵌入到Haskell中。這是最靈活,但也是最難取得進展的方式。
你確定他不只是在尋找sbv還是快速檢查?使用SBV:'證明$ \(x :: SInt32) - > 2 * x。== x + x'產生'Q.E.D.' –
@ ThomasM.DuBuisson很好的建議!我會將其添加到答案中。 –
我實際上是在尋找更深入的問題概覽,而這正是Daniel所提供的。 – MaiaVictor
除了在另一個答案中給出的實際例子之外,讓我們選擇在類型化lambda演算中可表達的函數的子集;我們也可以允許產品和總和類型。儘管檢查兩個函數是否相同可以像applying them to a variable and comparing results一樣簡單,但我們不能構建相等函數within the programming language itself。
ETA:λProlog是一種邏輯編程語言,用於操作(類型化的lambda微積分)函數。
2年過去了,但我想在這個問題上添加一點點評論。最初,我問是否有任何方法可以告訴(λx.2*x)
是否等於(λx.x+x)
。現在
add = (a b c -> (a b (a b c)))
mul = (a b c -> (a (b c)))
,如果您正常化以下條款:加法和乘法的λ演算可以被定義爲
add_x_x = (λx . (add x x))
mul_x_2 = (mul (λf x . (f (f x)))
你得到:
result = (a b c -> (a b (a b c)))
對於這兩種方案。由於它們的正常形式是平等的,所以這兩個節目顯然是平等的雖然這一般不起作用,但它在實踐中可以用於很多條款。例如,(λx.(mul 2 (mul 3 x))
和(λx.(mul 6 x))
都具有相同的標準形式。
有一種叫做「超級編譯」的技術(我推薦[this](http://community.haskell.org/~ndm/temp/supero.pdf)論文)。我想一個成熟的超級編譯器可以統一你的函數,即使它們是通過遞歸和模式匹配來定義的。 – user3237465
這是一般的不可判定的,而是一個合適的子集,可以有效地使用SMT求解器確實做到今天:
$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :m Data.SBV
Prelude Data.SBV> (\x -> 2 * x) === (\x -> x + x :: SInteger)
Q.E.D.
Prelude Data.SBV> (\x -> 2 * x) === (\x -> 1 + x + x :: SInteger)
Falsifiable. Counter-example:
s0 = 0 :: Integer
有關詳細信息,請參閱:https://hackage.haskell.org/package/sbv
與符號計算語言像數學:
MathObject f(MathObject x) => x + x;
MathObject g(MathObject x) => 2 * x;
{
var x = new Symbol("x");
Console.WriteLine(f(x) == g(x));
}
上面的控制檯顯示'True'。
但是,然而'(x \ [函數] x + x)==(y \ [函數] 2 y)'是在撒謊,它甚至不嘗試。 – tfb
證明兩個函數相等是一般不可判定的,但在特殊情況下仍然可以證明函數相等,就像在你的問題中一樣。
下面是精益
def foo : (λ x, 2 * x) = (λ x, x + x) :=
begin
apply funext, intro x,
cases x,
{ refl },
{ simp,
dsimp [has_mul.mul, nat.mul],
have zz : ∀ a : nat, 0 + a = a := by simp,
rw zz }
end
一個樣本證明可以做其他的依賴性類型的語言,如勒柯克,阿格達,伊德里斯相同。
以上是戰術風格證明。獲取生成foo
(證明)的實際定義是由手工寫得相當拗口:
def foo : (λ (x : ℕ), 2 * x) = λ (x : ℕ), x + x :=
funext
(λ (x : ℕ),
nat.cases_on x (eq.refl (2 * 0))
(λ (a : ℕ),
eq.mpr
(id_locked
((λ (a a_1 : ℕ) (e_1 : a = a_1) (a_2 a_3 : ℕ) (e_2 : a_2 = a_3), congr (congr_arg eq e_1) e_2)
(2 * nat.succ a)
(nat.succ a * 2)
(mul_comm 2 (nat.succ a))
(nat.succ a + nat.succ a)
(nat.succ a + nat.succ a)
(eq.refl (nat.succ a + nat.succ a))))
(id_locked
(eq.mpr
(id_locked
(eq.rec (eq.refl (0 + nat.succ a + nat.succ a = nat.succ a + nat.succ a))
(eq.mpr
(id_locked
(eq.trans
(forall_congr_eq
(λ (a : ℕ),
eq.trans
((λ (a a_1 : ℕ) (e_1 : a = a_1) (a_2 a_3 : ℕ) (e_2 : a_2 = a_3),
congr (congr_arg eq e_1) e_2)
(0 + a)
a
(zero_add a)
a
a
(eq.refl a))
(propext (eq_self_iff_true a))))
(propext (implies_true_iff ℕ))))
trivial
(nat.succ a))))
(eq.refl (nat.succ a + nat.succ a))))))
爲什麼downvote? – MaiaVictor
- 1. 如何比較兩個char []數組的等價性?
- 2. 比較兩個等價類
- 3. 如何比較兩個元素的等價性?
- 4. 比較兩個枚舉類型*的等價性?
- 5. 比較兩個等價類(續)
- 6. 如何比較cocos2d V3.x中的兩個CCSprite與IOS
- 7. expressionengine 2.x的相互EE標籤內比較兩個變量
- 8. 比較任意類型的兩個對象的等價性
- 9. Mysql比較使用左(X,2)=「AB」或X比如「AB%」的速度?
- 10. 如何比較兩個CFUUID(Mac OS X Carbon/CoreFoundation)?
- 11. iTextSharp比較2個PDF的相等性
- 12. 如何比較兩個數據框?
- 13. 比較兩個目錄的平等性
- 14. 我如何比較兩個數組?
- 15. 如何比較兩個對象在Scala中的相等性?
- 16. 如何比較兩個字符串在php中的相等性?
- 17. 如何爲Opencart 2.x中的比較產品動態鏈接?
- 18. 如何比較Coq中相同Set的兩個元素(相等)?
- 19. sqrt(x)和x **(1./2。)之間的比較
- 20. 如何比較python函數的性能?
- 21. 如何比較兩個DateTimeOffSet?
- 22. ndarray如何使用一個簡單的函數,如x ** 2?
- 23. AS3比較兩個函數
- 24. 兩個比較函數Mysql
- 25. VerQueryValue的MacOS X等價物?
- 26. 組成兩個比較函數?
- 27. 如果比較兩個序列相等
- 28. 如何比較SKSpritenodes的2個紋理
- 29. 比較平等的2個Properties對象
- 30. 奇數行爲比較雙倍,兩個PHP雙值不等價
你真的需要運算功能還是你只是好奇比較的功能呢?在後一種情況下,請看類型化的lambda結石的標準化。 – lukstafi
@lukstafi只是好奇,但我會看看它。 – MaiaVictor
你的連接詞「but」不合適,應該是「so」。 ;-) – lukstafi