Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 康达,康迪,康德,康杜_Clojure_Scheme_Clojure Core.logic_Minikanren_Reasoned Schemer - Fatal编程技术网

Clojure 康达,康迪,康德,康杜

Clojure 康达,康迪,康德,康杜,clojure,scheme,clojure-core.logic,minikanren,reasoned-schemer,Clojure,Scheme,Clojure Core.logic,Minikanren,Reasoned Schemer,我在看书 我对conde的工作原理有一些直觉 然而,我找不到一个正式的定义来定义conde/conda/condu/condi做什么 我知道,但这似乎有例子,而不是定义 用Prolog的术语来说,conde、conda、condi、condu是否有正式的定义 康达是“软切割”a.k.a.*->,其中a*->B;C就像(A,B;不是(A),C),只是更好 ; 鉴于 condU是“承诺的选择”,是一种一次和软剪切的组合,因此(一次(a)*->B;false)表示(a,!,B)(剪切在里面):

我在看书

我对conde的工作原理有一些直觉

然而,我找不到一个正式的定义来定义conde/
conda
/
condu
/
condi
做什么

我知道,但这似乎有例子,而不是定义

用Prolog的术语来说,
conde
conda
condi
condu
是否有正式的定义

  • 康达
    是“软切割”a.k.a.
    *->
    ,其中
    a*->B;C
    就像
    (A,B;不是(A),C)
    ,只是更好 ; 鉴于

  • condU
    是“承诺的选择”,是一种
    一次
    和软剪切的组合,因此
    (一次(a)*->B;false)
    表示
    (a,!,B)
    (剪切在里面):

condA:A*->B;C%软切,
%(A、B;非(A)、C)
条件:一次(A)*->B;C%承诺选择,
%(A,!,B;不是(A),C)
(分别用
表示“或”和
表示“和”,即目标的分离和连接)

condA
中,如果目标
A
成功,所有解决方案都会传递到第一个子句
B
,并且不会尝试任何替代子句
C

condU
中,
一次/1
只允许其参数目标成功一次(仅保留一个解决方案,如果有的话)

condE
是一个简单的连词析取,而
condI
是一个在其成分的溶液之间交替的析取,交错其中的流


下面是一个忠实地将本书的代码(包括逻辑变量和统一)翻译成18行Haskell的尝试,Haskell主要是一个带有语法的惰性Lisp,其中

  • 简单并置是当前函数应用程序,
    fabc=~=((fa)b)c)=~=f(a,b,c)
  • (\a->b)
    是lambda函数,
    (lambda(a)b)
  • foo x=y
    foo=(\x->y)
  • a@b=y
    (@)a b=y
    的快捷方式,中缀运算符的定义
    @
  • 括号
    仅用于分组
  • []
    是空列表,并且
  • 表示cons——在定义中位于
    =
    右侧的构造函数(惰性,因为整个语言都是惰性的,即根据需要调用);作为一种分解模式,在左侧(或在模式匹配
    case
    表达式中)
看看这是否澄清了问题:

  • 顺序流组合(“本书的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=gx++:(xs>>:g)
    
  • 交替馈送(“
    bindI
    ”):

    (7)[]>/g=[]
    (8) (x:xs)>>/g=gx++/(xs>>/g)
    
  • ”目标组合(
    condE
    ”):

    (9)(f | |:g)x=f x++:g x
    
  • “交替
    ”目标组合(
    condI
    ):

    (10)(f | |/g)x=f x++/g x
    
  • ”目标组合(
    全部
    ”):

    (11)(f&&:g)x=fx>:g
    
  • “交替的
    ”目标组合(“本书的
    allI
    ”):

    (12)(f&/g)x=f x>>/g
    
  • 特殊目标

    (13)true x=[x]--重新打包相同解决方案的sigleton列表
    (14) false x=[]--一个空列表,表示该解决方案被拒绝
    
给定问题的(可能是部分)解决方案,目标生成(可能是空的)解决方案流(可能是更新的)

所有
的重写规则为:

(全部)=真
(全部g1)=g1
(所有g2 g3…=(\x->g1 x>>:(所有g2 g3…)
=g1&:(g2&:(g3&:…)
(allI g1 g2 g3…=(\x->g1 x>>/(allI g2 g3…)
=g1&/(g2&/(g3&/)
condX
的重写规则为:

(condX)=错误
(condX(其他g1-g2…)=(所有g1-g2…)=g1&:(g2&&:(…)
(condX(g1-g2…)=(所有g1-g2…)=g1&:(g2&:(…)
(condX(g1-g2…)(h1-h2…)=(ifX-g1(所有g2…)
(ifX h1(所有h2…))
为了最终实现condE和condI的翻译,无需实现本书的ifE和ifI,因为它们进一步简化为简单的运算符组合,所有操作符都被认为是右关联的:

(冷凝器(g1 g2…(h1 h2…)=
(g1&&:g2&&:…)| |:(h1&&:h2&:…)|:。。。
(条件(g1 g2…(h1 h2…)=
(g1&&:g2&:…)| |/(h1&&:h2&:…)|//。。。
所以在Haskell中不需要任何特殊的“语法”,简单的二进制中缀运算符就足够了。
user>  (run* [w q]
                (conde [u#]
                       [(or* [(== w 1) (== w 2)])
                        (== q :first)]
                       [(== q :second)]))
([_0 :second] [1 :first] [2 :first])
user> (run* [w q]
                (conda [u#]
                       [(or* [(== w 1) (== w 2)])
                        (== q :first)]
                       [(== q :second)]))
([1 :first] [2 :first])
user> (run* [w q]
                (condu [u#]
                       [(or* [(== w 1) (== w 2)])
                        (== q :first)]
                       [(== q :second)]))
([1 :first])
once(A) *-> B;C