孔德孔德孔德驱动孔德孔德孔德驱动(conda, condi, conde, condu)

2019-05-16 20:35发布

我读了合理的策士 。

我有一些如何直觉conde的作品。

但是,我找不到什么正式的定义conde / conda / condu / condi做的。

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

有没有一个正式的定义condecondacondicondu地方?

Answer 1:

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

要在最终到达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) 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

这样,最后,对于重写规则condAcondU书的只是:

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

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


Answer 2:

理由充分的策士涵盖康达 (软切)和condu(提交选择)。 您还可以找到自己的威廉伯德的优秀行为的解释上miniKanren论文 。 您已经标记了这篇文章为约core.logic。 需要明确的是core.logic是基于一个较新版本miniKanren比在理由充分的策士提出的一个。 miniKanren总是交错析取的目标- 康迪和交织变种不再存在。 孔德现在 赖斯



Answer 3:

通过实施例,使用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])

不知道是什么但是赖斯一样。



Answer 4:

根据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的存档。



文章来源: conda, condi, conde, condu