conda,condi,conde,condu

我正在阅读Reasoned Schemer 。

我有一些关于conde如何工作的直觉。

然而,我无法findconde / condu / condu / condu做什么的正式定义。

我知道https://www.cs.indiana.edu/~webyrd/,但似乎有例子,而不是定义。

condeconducondu有什么正式的定义吗?

在Prolog的术语中, condA“软切”*->condU“承诺select”once和软切的组合,所以(once(A) *-> B ; false)表示切入 (A, !, B)

 A *-> B ; C %% soft cut, condA once(A) *-> B ; C %% committed choice, condU 

condA ,如果目标A成功了,所有的解决scheme都被传递给第一个子句B并且没有可选的子句C被尝试。 once/1允许其论证目标只能成功一次(只保留一个解决scheme,如果有的话)。

condE是一个简单的condI ,而condI是一个在其组成部分的解决scheme之间交替的分离。


这里试图忠实地将本书的代码(无论是逻辑variables还是统一)翻译成18行Haskell(其中并置是curried函数应用程序,意思是cons )。 看看是否澄清事情:

  • 顺序stream组合(本书的“ mplus ”):
  (1) [] ++: ys = ys (2) (x:xs) ++: ys = x:(xs ++: ys) 
  • 交替stream组合(“ mplusI ”):
  (3) [] ++/ ys = ys (4) (x:xs) ++/ ys = x:(ys ++/ xs) 
  • 顺序饲料(“ bind ”):
  (5) [] >>: g = [] (6) (x:xs) >>: g = gx ++: (xs >>: g) 
  • 交替饲料(“ bindI ”):
  (7) [] >>/ g = [] (8) (x:xs) >>/ g = gx ++/ (xs >>/ g) 
  • OR目标组合(“ condE ”):
  (9) (f ||: g) x = fx ++: gx 
  • “交替OR ”目标组合(“ condI ”):
  (10) (f ||/ g) x = fx ++/ gx 
  • AND ”目标组合(“ all ”):
  (11) (f &&: g) x = fx >>: g 
  • “交替AND ”目标组合(本书的“ allI ”):
  (12) (f &&/ g) x = fx >>/ g 
  • 特殊的目标
  (13) true x = [x] -- a sigleton list with the same solution repackaged (14) false x = [] -- an empty list, meaning the solution is rejected 

目标产生(可能更新的)解决scheme的stream(可能是空的),给出一个问题(可能是部分的)解决scheme。

重新编写规则是:

 (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 ...) (...) )) 

为了达到最终的condEcondI的翻译,没有必要实施本书的ifEifI ,因为它们进一步简化为简单的操作符组合,所有操作符被认为是正确关联的

 (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) fx = case gx of [] -> fx ; ys -> ys >>: h 
  • 一个“尝试”目标和一个简单目标的“ OR-ELSE ”目标组合简单地将其“尝试”目标与第二个失败目标称为“失败”目标,所以它只不过是操作数自动分组的便利语法:
  (16) (g ||~ f) x = gfx 

如果||~OR-ELSE ”运算符的结合能力比~~>IF-THEN ”运算符的结合能力还要低,并且运算符的结合能力还不如&&:上面例子的合理分组是自动生成的

 (g1 ~~> (g2 &&: ...)) ||~ ( (h1 ~~> (h2 &&: ...)) ||~ (... ||~ gelse)...) 

因此,链条的最终目标是一个简单的目标。 这实际上没有什么限制,因为condAforms的最后一个语句和简单的“ AND ” – 它们的目标组合(或简单的false也可以同样使用)是等价的。

就这样。 如果我们想要,我们甚至可以有更多types的尝试目标,由不同种类的“ IF ”运算符来表示:

  • 在一个成功的条款中使用交替馈送(如果本书中有一个可以称为condAI ):
  (17) (g ~~>/ h) fx = case gx of [] -> fx ; ys -> ys >>/ h 
  • 使用成功的解决schemestream只产生一次 剪切效果,以build模condU
  (18) (g ~~>! h) fx = case gx of [] -> fx ; (y:_) -> hy 

所以,最后,书的condAcondU的重写规则是简单的:

 (condA (g1 g2 ...) (h1 h2 ...) ...) = g1 ~~> g2 &&: ... ||~ h1 ~~> h2 &&: ... ||~ ... (condU (g1 g2 ...) (h1 h2 ...) ...) = g1 ~~>! g2 &&: ... ||~ h1 ~~>! h2 &&: ... ||~ ... 

理性的策略涵盖conda (软切)和道德 (承诺的select)。 你也可以在William Byrd 关于miniKanren的优秀论文中find他们的行为解释。 你已经标记这篇文章是关于core.logic。 要明确core.logic是基于一个比The Reasoned Schemer中提出的更新的miniKanren版本。 miniKanren总是交错分离的目标 – condi和交错变种不再存在。 conde现在 condi

通过例子,使用core.logic:

conde将运行每个组,如果至less有一个组成功,则返回所有成功组的所有结果。

 user> (run* [wq] (conde [u#] [(or* [(== w 1) (== w 2)]) (== q :first)] [(== q :second)])) ([_0 :second] [1 :first] [2 :first]) 

conda和conduit:在第一个成功的团队(从上到下)之后都会停止,

conda只返回来自第一个成功组的所有结果。

 user> (run* [wq] (conda [u#] [(or* [(== w 1) (== w 2)]) (== q :first)] [(== q :second)])) ([1 :first] [2 :first]) 

只从第一个成功的小组返回一个结果。

 user> (run* [wq] (condu [u#] [(or* [(== w 1) (== w 2)]) (== q :first)] [(== q :second)])) ([1 :first]) 

不知道condi做什么。