Lambda 在Prolog查询中隐藏变量

Lambda 在Prolog查询中隐藏变量,lambda,prolog,Lambda,Prolog,我正在与prolog一起完成一项任务,该任务涉及机场数据库(它有机场城市和航班链接,其中包括机场税和持续时间),第一个问题涉及查询。我们应该写一个Prolog查询来回答一个问题,我已经知道如何回答这个问题,问题是Prolog输出的信息比我想要的要多。我写的查询是: flight(X,_,Y,_,N), N > 180. 基本上,它所做的就是列出所有城市(X是始发航班,Y是目的地航班,N是持续时间)。我想要X和Y,但我不想要N。我能想到的唯一方法是将这个查询包装在一个规则中,让它显示X和

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

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

基本上,它所做的就是列出所有城市(X是始发航班,Y是目的地航班,N是持续时间)。我想要X和Y,但我不想要N。我能想到的唯一方法是将这个查询包装在一个规则中,让它显示X和Y,但由于我们不应该编写规则,我不知道如何绕过它。我真的不想得到一个明确的答案,也许只是一个提示或什么的。

以下是否提供了一个可接受的解决方案
findall
查找满足给定目标的给定术语的所有统一。因此,您可以根据自己的意愿设置答案的格式

findall([X, Y], (flight(X, _, Y, _, N), N > 180), Solutions).

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

flight(X,_,Y,_,N), N > 180, print(('X' = X, 'Y' = Y)), nl, fail.
这样做的缺点是:

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

  • 更糟糕的是,这个目标实际上失败了(为了防止它成功地打印出许多虚假的绑定,比如
    N
    ),因此很难在更大的系统中使用


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

    如果可能,我更喜欢使用表达式来压缩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.
    

    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源于 (^)/2已在bagof/3和setof/3谓词中找到

    再见

    使用,您可以声明那些应该保持可见的变量

    ?- {X,Y}+\ ( flight(X,_,Y,_,N), N > 180 ).
    X = c,
    Y = d.
    

    嘿,谢谢你的回答,虽然我们不允许使用任何可能包括forall。。。虽然它很有效,但这是一个很好的知识,即使我不允许使用它,我相信类似的东西可能会对作业的其他部分有所帮助!嘿,谢谢你的更新,我确实想到了这一点,但我不清楚我是否能做到,因为这需要写一条规则。我知道在查询中我只需要问查询(X,Y)就行了,但在作业中它说“对于下面列出的每个问题(a)-(e),写一个Prolog查询(不是规则!),它将使用flight/5和airport/3谓词以及您需要的任何其他逻辑来回答问题。我可能只是误解了作业的规则(没有双关语的意思:)嗯……有趣的是,自从这门课开始,我就没有用prolog写过东西,但如果我决定回到这门课上,我会尽量记住这一点。我知道我们有一个人工智能类,我们必须用prolog写,所以如果我上这个类,这可能是一件值得记住的事情:)在许多实现中,(^)/2被实现为
    (^^G):-G.
    lambda序言中的(^)/2对应于sigma/1和(\)/2:[列表]?-sigma Y\append X Y(1::nil)。X=nil