假设以下程序:
nat(0).
nat(s(N)) :- nat(N).
/* 0+b=b */
plus(0,B,B) :- nat(B).
/* (a+1)+b = c iff a+(b+1)=c */
plus(s(A),B,C) :- plus(A,s(B),C).
Run Code Online (Sandbox Code Playgroud)
它适用于添加两个数字,但是当我尝试查询以下类型时:
plus(Z,Z,s(0)).
Run Code Online (Sandbox Code Playgroud)
它继续搜索可能的值Z很长时间后应该很明显没有解决方案(即Z>s(0))
我熟悉cut(!)运算符,我的直觉说解决方案与它有关,我只是不确定如何在这种情况下使用它.
prolog logic-programming backtracking successor-arithmetics failure-slice
我正在阅读Prolog中关于上下文无关语法的本教程,他们在页面底部提到使用差异列表在Prolog中实现上下文无关语法,包括以下代码块:
s(X,Z):- np(X,Y), vp(Y,Z).
np(X,Z):- det(X,Y), n(Y,Z).
vp(X,Z):- v(X,Y), np(Y,Z).
vp(X,Z):- v(X,Z).
det([the|W],W).
det([a|W],W).
n([woman|W],W).
n([man|W],W).
v([shoots|W],W).
Run Code Online (Sandbox Code Playgroud)
它提到:
仔细考虑这些规则.例如,s规则说:我知道一对列表X和Z表示一个句子,如果(1)我可以消耗X并留下Y,而X和Y对代表一个名词短语,(2)然后我可以继续消耗Y而将Z留在后面,而YZ代表一个动词短语.np规则和第二个vp规则的工作方式类似.
和
将第一个列表视为需要消耗的内容(或者如果您愿意:输入列表),将第二个列表视为我们应该留下的内容(或:输出列表).从这个(相当程序上)的角度来看差异列表
Run Code Online (Sandbox Code Playgroud)[a,woman,shoots,a,man] [].代表一个女人射杀一个男人的句子,因为它说:如果我消耗左边的所有符号,并留下右边的符号,那么我就有我感兴趣的句子.也就是说,我们感兴趣的句子是这两个列表的内容之间的差异.
这就是我们需要知道的差异列表来重写我们的识别器.如果我们只是牢记消费某些东西的想法,并留下一些东西,我们会获得以下认知:
作为解释,但这只是没有做任何事情来澄清这段代码给我.我知道它比使用更有效append/3,但至于消费和留下其他人的概念,它似乎比以前的append/3实现更令人困惑,我只是无法做出正面或反面.此外,当我将该代码复制并粘贴到Prolog可视化工具中以试图理解它时,可视化工具表示存在错误.谁能对此有所了解?
我开始学习 Prolog,我刚刚读到结构开头的原子通常称为函子。
我还熟悉范畴论和函数式编程中的术语函子。
所以我的问题是,Prolog 中函子一词的选择对范畴论有什么影响吗?Prolog 中的函子是一种变换吗?或者这个名字的选择仅仅是巧合?
非常感谢!
functional-programming prolog logic-programming functor category-theory
这是一个(希望)简单的逻辑程序,我已经坚持了一段时间.
我在core.logic中有一个由边缘关系表示的DAG,当生成父节点列表时,当我在图中有"菱形"时,我得到重复(我不是在讨论这里的循环).
在这种情况下,有没有办法生成一个明确的父母列表(通过重写父母或类似的东西)?
(defrel edge a b)
(fact edge :a :b)
(fact edge :a :c)
(fact edge :b :d)
(fact edge :c :d)
(defne parento [x y]
([x y] (edge y x))
([x y] (fresh [z]
(edge z x)
(parento z y))))
(run* [q] (parento :d q))
;; => (:b :c :a :a)
Run Code Online (Sandbox Code Playgroud)
我想得到(:b:c:a)并且我想在run*语句中执行它(即将结果包装在一个集合中并不是我的目标).
此外,将"^:tabled"添加到parento似乎可以解决问题,但我不想要tabled介绍的memoization.
I am curious about how tabling works to improve efficiency of Prolog programs. How is it implemented? Both explanation and references are welcome.
逻辑编程和自动定理证明(ATP)之间有什么区别(例如使用E-Prover,Spass或Princess)?
我搜索了很多,我发现的唯一信息是ATP是逻辑编程的先驱.但我没有看到差异.但我想这不仅仅是语法.
我目前正在学习 The Reasoned Schemer 和 Racket 的 miniKanren。
我有三个版本的 minikanren 实现:
《理性策划者》,第一版(麻省理工学院出版社,2005 年)。我叫它TRS1
https://github.com/miniKanren/TheReasonedSchemer
附言。它说它已被执行交错的condi改进版本所取代。conde
《理性的阴谋家》,第二版(麻省理工学院出版社,2018 年)。我叫它TRS2
https://github.com/TheReasonedSchemer2ndEd/CodeFromTheReasonedSchemer2ndEd
《理性策划者》,第一版(麻省理工学院出版社,2005 年)。我叫它TRS1*
我对上面的三种实现做了一些实验:
第一个实验:
TRS1
(run* (r)
(fresh (x y)
(conde
((== 'a x) (conde
((== 'c y) )
((== 'd y))))
((== 'b x) (conde
((== 'e y) )
((== 'f y)))))
(== `(,x ,y) r)))
;; => '((a c) (a d) (b e) (b f))
Run Code Online (Sandbox Code Playgroud)
TRS2
(run* (x y)
(conde
((== 'a x) …Run Code Online (Sandbox Code Playgroud) 是否有任何语言使用任意逻辑编程执行编译时优化?
我正在寻找一种语言示例,使您能够执行以下操作:
is-idempotent?f(f(x))等于f(x)如果该is-idempotent?功能是真正的fis-idempotent?各种功能(可能是间接的,例如由其他逻辑语句暗示)language-agnostic compiler-construction programming-languages logic-programming
MiniKanren 有“非”运算符吗?
例如,如何表示 Prolog 的
a :- b, not(c)
Run Code Online (Sandbox Code Playgroud)
a如果b为真则为真c而不为真(Prolog 使用否定作为失败,即 not(c)如果c无法证明则认为已证明)
Prolognot也适用于非基础表达式,例如
a(X, d(Y)) :- b(d(X), d(Y)), not(c(d(X)))
Run Code Online (Sandbox Code Playgroud) clojure logic-programming negation minikanren clojure-core.logic
Prolog 中的高阶编程风格在 HiLog 和 ?Prolog 中首创。
HiLog的动机包括其实现高阶谓词的能力,例如maplist:
maplist(F)([],[]).
maplist(F)([X|Xs],[Y|Ys]) <- F(X,Y), maplist(F)(Xs,Ys).
Run Code Online (Sandbox Code Playgroud)
描述 HiLog 的论文假设 Prolog 只有call/1,没有call/3。
但是,由于 Prolog(现在)有call/3,maplist可以很容易地在其中实现:
maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :- call(P, X, Y), maplist(P, Xs, Ys).
Run Code Online (Sandbox Code Playgroud)
HiLog 是否主要具有历史意义,或者它的“高阶”逻辑是否比 Prolog 现在可用的更通用?