6

我正在处理涉及机场数据库的序言任务(它有机场城市,以及包括机场税和持续时间的航班链接),第一个问题涉及查询。我们应该编写一个 Prolog 查询来回答一个问题,我已经知道如何回答这个问题,问题是 Prolog 输出的信息比我想要的多。我写的查询是:

flight(X,_,Y,_,N), N > 180. 

基本上它所做的只是列出所有城市(X 是始发航班,Y 是目的地航班,N 是持续时间)。我想要 X 和 Y 但我不想 N我不知道如何解决这个问题。我真的不想要一个明确的答案,也许只是一个提示或什么。

4

5 回答 5

3

在可能的情况下,我更喜欢使用表达式来压缩 IO

?- forall((flight(X,_,Y,_,N), N > 180),
           writeln((x=X,y=Y))).

例如,使用不同的生成器

?- forall((member(X,"12"),member(Y,"ab")),writeln((x=X,y=Y))).
x=49,y=97
x=49,y=98
x=50,y=97
x=50,y=98
true.

当然,正确缩进表格格式/2 会做得更好......

编辑 也许我误解了这个问题,假设你已经考虑过

query(X,Y) :-
  flight(X,_,Y,_,N), N > 180.
于 2012-11-25T22:09:50.087 回答
1

Jekejeke Prolog 为这个问题提供了独特的解决方案。它允许 (^)/2 运算符出现在顶级查询中。因此,如果您有:

?- [user].
flight(a,1,b,2,100).
flight(c,3,d,4,200).
^D

您通常会得到以下答案,而 N 可能会惹恼您:

?- flight(X,_,Y,_,N), N > 180.
X = c,
Y = d,
N = 200

您现在可以按如下方式隐藏 N:

?- N^(flight(X,_,Y,_,N), N>180).
X = c,
Y = d

为此目的使用 (^)/2 源于在 bagof/3 和 setof/3 谓词中已经找到的 (^)/2 的作用。

再见

于 2013-04-03T22:51:06.717 回答
1

使用library(lambda)您可以声明那些应该保持可见的变量。

?- {X,Y}+\ ( flight(X,_,Y,_,N), N > 180 ).
X = c,
Y = d.
于 2013-05-12T22:26:30.473 回答
0

对于这样的一次性查询,我经常使用简单的打印语句,例如:

flight(X,_,Y,_,N), N > 180, print(('X' = X, 'Y' = Y)), nl, fail.

这样做的缺点是:

  1. 输出可能很难看,除非您对它进行格式化。在这里,我正在构建一个,/2术语(带有=/2子术语),它应该类似于普通目标解决方案的 Prolog 输出。

  2. 更糟糕的是,目标实际上失败了(以防止它成功打印所有许多虚假绑定,例如 for N),因此很难在更大的东西中使用。

但这是我所知道的打印一组在命令行中输入的目标的解决方案的最快方法,同时隐藏所有工作变量。

于 2012-11-25T21:37:51.847 回答
-1

以下是否提供了可接受的解决方案?findall找到满足给定目标的给定术语的所有统一. 因此,您可以根据需要格式化您的答案。

findall([X, Y], (flight(X, _, Y, _, N), N > 180), Solutions).
于 2012-11-25T21:17:58.090 回答