我在閱讀the Reasoned Schemer。conda,condi,conde,condu
我對conde
的工作原理有一些直覺。
但是,我找不到什麼conde
/conda
/condu
/condi
做的正式定義。我知道https://www.cs.indiana.edu/~webyrd/但這似乎有例子,而不是定義。
conde
,conda
,condi
,condu
是否有正式的定義?
我在閱讀the Reasoned Schemer。conda,condi,conde,condu
我對conde
的工作原理有一些直覺。
但是,我找不到什麼conde
/conda
/condu
/condi
做的正式定義。我知道https://www.cs.indiana.edu/~webyrd/但這似乎有例子,而不是定義。
conde
,conda
,condi
,condu
是否有正式的定義?
在Prolog的話來說,condA
是「軟切」,*->
,並condU
是「犯選擇」 –的once
組合和柔軟的剪裁,讓(once(A) *-> B ; false)
表達剪切在(A, !, B)
:
A *-> B ; C %% soft cut, condA
once(A) *-> B ; C %% committed choice, condU
condA
,如果目標A
成功,則將所有解決方案傳遞給第一個子句B
,並且未嘗試替代子句C
。 once/1
允許其論證目標只能成功一次(只保留一個解決方案,如果有的話)。
condE
是一個簡單的析取,並condI
是其成分的解決方案之間交替的析取。
下面是在忠實地平移所述書的代碼,瓦特/輸出邏輯變量和統一,到18行的Haskell的嘗試(其中並置是咖喱功能的應用程序,:
裝置缺點)。看看這個澄清的事情:
mplus
」一書):(1) [] ++: ys = ys
(2) (x:xs) ++: ys = x:(xs ++: ys)
mplusI
」):(3) [] ++/ ys = ys
(4) (x:xs) ++/ ys = x:(ys ++/ xs)
bind
」):(5) [] >>: g = []
(6) (x:xs) >>: g = g x ++: (xs >>: g)
bindI
」):(7) [] >>/ g = []
(8) (x:xs) >>/ g = g x ++/ (xs >>/ g)
OR
」 目標組合( 「condE
」):(9) (f ||: g) x = f x ++: g x
OR
」 目標組合(「 condI
」):(10) (f ||/ g) x = f x ++/ g x
AND
」 的目標組合( 「all
」):(11) (f &&: g) x = f x >>: g
AND
」 的目標相結合(的「 allI
」 一書):(12) (f &&/ g) x = f x >>/ g
(13) true x = [x] -- a sigleton list with the same solution repackaged
(14) false x = [] -- an empty list, meaning the solution is rejected
的(可能已更新)解決方案,給定(可能局部的)的解決方案的一個問題目標產品流(可能爲空)。
爲all
重新編寫規則是:
(all) = true
(all g1) = g1
(all g1 g2 g3 ...) = (\x -> g1 x >>: (all g2 g3 ...))
=== g1 &&: (g2 &&: (g3 &&: ...))
(allI g1 g2 g3 ...) = (\x -> g1 x >>/ (allI g2 g3 ...))
=== g1 &&/ (g2 &&/ (g3 &&/ ...))
爲condX
重新編寫規則是:
(condX) = false
(condX (else g1 g2 ...)) = (all g1 g2 ...) === g1 &&: (g2 &&: (...))
(condX (g1 g2 ...)) = (all g1 g2 ...) === g1 &&: (g2 &&: (...))
(condX (g1 g2 ...) (h1 h2 ...) ...) =
(ifX g1 (all g2 ...) (ifX h1 (all h2 ...) (...)))
要在最後condE
和condI
到達翻譯,t這裏是沒有必要實施本書的ifE
和ifI
,因爲它們進一步降低到簡單操作的組合,與被認爲是右關聯的所有運營商:
(condE (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ...) ||: (h1 &&: h2 &&: ...) ||: ...
(condI (g1 g2 ...) (h1 h2 ...) ...) =
(g1 &&: g2 &&: ...) ||/ (h1 &&: h2 &&: ...) ||/ ...
所以沒有必要對任何Haskell中特殊的「語法」,普通的運算符就足夠了。可以使用任何組合,如果需要,可以使用&&/
而不是&&:
。但OTOH condI
也可以實現爲接受要實現的目標的集合(列表,樹等)的函數,其將使用一些智能策略來挑選它們中最可能或最需要的一個等等,而不僅僅是簡單的二元交替,如||/
運營商(或ifI
的書)。
其次,這本書的condA
可以通過兩種新的運營商,~~>
和||~
,同心協力進行建模。我們可以以自然的方式使用它們,例如,
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ... ||~ gelse
它可以直觀地被讀作「IF g1 THEN g2 AND ... OR-ELSE IF h1 THEN ... OR-ELSE gelse
」。
IF-THEN
」的目標組合是生產必須以失敗延續進球被稱爲「試一試」的目標:(15) (g ~~> h) f x = case g x of [] -> f x ; ys -> ys >>: h
OR-ELSE
」的目標,結合「嘗試「目標和一個簡單的目標只是簡單地將其」嘗試「目標稱爲失敗後的第二個目標,所以它只不過是用於自動分組操作數的便利語法:(16) (g ||~ f) x = g f x
如果||~
「OR-ELSE
」算符給出更低結合力比~~>
「IF-THEN
」運營商和製造右關聯也和~~>
運營商仍然較少結合力比&&:
和上面的一樣,明智的分組示例是自動製造
(g1 ~~> (g2 &&: ...)) ||~ ((h1 ~~> (h2 &&: ...)) ||~ (... ||~ gelse)...)
在||~
鏈最後目標必須因而是一個簡單的目標。真的沒有什麼限制,因爲condA
的最後一個條款無論如何都是簡單的「AND
」 - 它的目標組合(或簡單的false
也可以使用)。
就是這樣。我們甚至可以有更多類型的嘗試,目標,通過不同種類的「IF
」運營商的代表,如果我們想:一個成功的條款
condAI
,如果有一個在這本書):(17) (g ~~>/ h) f x = case g x of [] -> f x ; ys -> ys >>/ h
condU
:(18) (g ~~>! h) f x = case g x of [] -> f x ; (y:_) -> h y
這樣,最後,condA
和書的condU
重新寫入規則是簡單的:
(condA (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ...
(condU (g1 g2 ...) (h1 h2 ...) ...) =
g1 ~~>! g2 &&: ... ||~ h1 ~~>! h2 &&: ... ||~ ...
The Reasoned Schemer涵蓋了conda(soft cut)和condu(承諾選擇)。您還可以在William Byrd的優秀dissertation on miniKanren中找到他們的行爲解釋。您已將此帖標記爲關於core.logic。要明確core.logic是基於最近版本的miniKanren,而不是在The Reasoned Schemer中提出的版本。 miniKanren總是插入分離目標 - condi並且交織變體不再存在。 condeiscondi now。
通過實例,使用core.logic:
孔德將運行每個小組,成功,如果至少一個組成功,回報所有成功的組中的所有結果。
user> (run* [w q]
(conde [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([_0 :second] [1 :first] [2 :first])
暢達和condu:雙方將停止在第一次成功後組(從上到下)
暢達收益僅第一個成功的組中的所有結果。
user> (run* [w q]
(conda [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first] [2 :first])
condu 返回只從第一組成功只有一個結果。
user> (run* [w q]
(condu [u#]
[(or* [(== w 1) (== w 2)])
(== q :first)]
[(== q :second)]))
([1 :first])
不知道雖然condi做了什麼。
不是一個正式的定義,但它可能有助於 – paulocuneo
作爲dnolen在他的答案寫在這裏,核心.logic conde是本書的condi。本書的conde按順序處理其子目標。如果第一個連續的子目標產生了無限的答案流,那麼在組合解決方案流中就不會出現其他成功的子目標解決方案。本書的條件通過交織流來補救。 –
真棒!現在我明白了。沒有趕上流/交錯部分回來時。 從現在開始重新審視core.logic src – paulocuneo
5堆棧溢出不值得這個響應。我希望你把它變成博客文章或其他東西。 – user1383359
作爲後續:COND? == OR?和所有? == AND? ? – user1383359
@ user1383359或多或少。 COND是Prolog的OR(析取),ALL - Prolog的AND(聯合)。 CONDi,ALLi是子目標解決方案合併秩序的一種變體,試圖將預先將非生產性行爲預先納入系統。 –