标签: logic-programming

如何阻止prolog无限地检查不可能的解决方案?

假设以下程序:

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

7
推荐指数
1
解决办法
596
查看次数

这个上下文无关语法如何使用Prolog功能中的差异列表?

我正在阅读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规则的工作方式类似.

将第一个列表视为需要消耗的内容(或者如果您愿意:输入列表),将第二个列表视为我们应该留下的内容(或:输出列表).从这个(相当程序上)的角度来看差异列表

[a,woman,shoots,a,man]  [].
Run Code Online (Sandbox Code Playgroud)

代表一个女人射杀一个男人的句子,因为它说:如果我消耗左边的所有符号,并留下右边的符号,那么我就有我感兴趣的句子.也就是说,我们感兴趣的句子是这两个列表的内容之间的差异.

这就是我们需要知道的差异列表来重写我们的识别器.如果我们只是牢记消费某些东西的想法,并留下一些东西,我们会获得以下认知:

作为解释,但这只是没有做任何事情来澄清这段代码给我.我知道它比使用更有效append/3,但至于消费和留下其他人的概念,它似乎比以前的append/3实现更令人困惑,我只是无法做出正面或反面.此外,当我将该代码复制并粘贴到Prolog可视化工具中以试图理解它时,可视化工具表示存在错误.谁能对此有所了解?

parsing prolog logic-programming dcg difference-lists

7
推荐指数
1
解决办法
547
查看次数

Prolog 中的术语“函子”与范畴论中的术语有任何关系吗?

我开始学习 Prolog,我刚刚读到结构开头的原子通常称为函子

我还熟悉范畴论和函数式编程中的术语函子。

所以我的问题是,Prolog 中函子一词的选择对范畴论有什么影响吗?Prolog 中的函子是一种变换吗?或者这个名字的选择仅仅是巧合?

非常感谢!

functional-programming prolog logic-programming functor category-theory

7
推荐指数
1
解决办法
228
查看次数

使用core.logic列出唯一的DAG父级

这是一个(希望)简单的逻辑程序,我已经坚持了一段时间.

我在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.

clojure logic-programming minikanren clojure-core.logic

6
推荐指数
1
解决办法
296
查看次数

How does tabling improve efficiency?

I am curious about how tabling works to improve efficiency of Prolog programs. How is it implemented? Both explanation and references are welcome.

prolog logic-programming prolog-tabling

6
推荐指数
0
解决办法
924
查看次数

逻辑编程和自动定理证明之间的区别

逻辑编程和自动定理证明(ATP)之间有什么区别(例如使用E-Prover,Spass或Princess)?

我搜索了很多,我发现的唯一信息是ATP是逻辑编程的先驱.但我没有看到差异.但我想这不仅仅是语法.

prolog logic-programming theorem-proving

6
推荐指数
1
解决办法
465
查看次数

阐明不同 minikanren 实现中的搜索算法

我目前正在学习 The Reasoned Schemer 和 Racket 的 miniKanren。

我有三个版本的 minikanren 实现:

  1. 《理性策划者》,第一版(麻省理工学院出版社,2005 年)。我叫它TRS1

    https://github.com/miniKanren/TheReasonedSchemer

    附言。它说它已被执行交错的condi改进版本所取代。conde

  2. 《理性的阴谋家》,第二版(麻省理工学院出版社,2018 年)。我叫它TRS2

    https://github.com/TheReasonedSchemer2ndEd/CodeFromTheReasonedSchemer2ndEd

  3. 《理性策划者》,第一版(麻省理工学院出版社,2005 年)。我叫它TRS1*

    https://docs.racket-lang.org/minikanren/

我对上面的三种实现做了一些实验:

第一个实验:

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)

scheme logic-programming racket minikanren reasoned-schemer

6
推荐指数
1
解决办法
319
查看次数

使用逻辑编程优化的语言

是否有任何语言使用任意逻辑编程执行编译时优化?

我正在寻找一种语言示例,使您能够执行以下操作:

  • 定义任意谓词,例如 is-idempotent?
  • 告诉编译器f(f(x))等于f(x)如果该is-idempotent?功能是真正的f
  • 指定is-idempotent?各种功能(可能是间接的,例如由其他逻辑语句暗示)
  • 让编译器根据它所知道的谓词/优化来执行优化

language-agnostic compiler-construction programming-languages logic-programming

5
推荐指数
1
解决办法
130
查看次数

MiniKanren 有“非”运算符吗?

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

5
推荐指数
1
解决办法
668
查看次数

HiLog 是否添加了 Prolog 中“调用”无法完成的任何内容?

Prolog 的维基百科文章指出:

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 现在可用的更通用?

prolog logic-programming xsb

5
推荐指数
1
解决办法
152
查看次数