我读了合理的策士 。
我有一些如何直觉conde
的作品。
但是,我找不到什么正式的定义conde
/ conda
/ condu
/ condi
做的。
我所知道的https://www.cs.indiana.edu/~webyrd/但似乎刚才的例子,而不是定义。
有没有一个正式的定义conde
, conda
, condi
, 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
的翻译,就没有必要执行书的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 &&: ... ||~ ...
理由充分的策士涵盖康达 (软切)和condu(提交选择)。 您还可以找到自己的威廉伯德的优秀行为的解释上miniKanren论文 。 您已经标记了这篇文章为约core.logic。 需要明确的是core.logic是基于一个较新版本miniKanren比在理由充分的策士提出的一个。 miniKanren总是交错析取的目标- 康迪和交织变种不再存在。 孔德现在是 赖斯 。
通过实施例,使用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])
不知道是什么但是赖斯一样。
根据ISO的Prolog芯标准控制结构,例如(,)/ 2,(;)/ 2和( - >)/ 2被切割透明的。 (* - >)/ 2未在ISO Prolog的核心标准发现,但通常的Prolog系统实现它也切断透明的。
这意味着一个无法翻译:
once(A) *-> B;C
成A, !, B; C
A, !, B; C
。 因为以后可能会被嵌入到其他控制结构,如果有其中析取,这些选择点也将发切掉。 在另一方面什么似乎是合理的,将其视为A -> B; C
A -> B; C
,
简称为ISO Prolog的核心标准的if-then-else的 。 将如此限定的切口的行为,例如是打出来重复循环是有用的,未抛出异常。 通常的编程模式是更加困难的if-then-else的存档。