简体   繁体   English

如何列出 Prolog 查询,然后以编程方式打印每个查询及其结果?

[英]How to you list Prolog queries and then print each query and its result(s) programmatically?

I have the following file named movies.pl :我有以下名为movies.pl的文件:

acted_in('Brad Pitt', 'Babel').
acted_in('Cate Blanchett', 'Babel').
acted_in('Sharlto Copley', 'District 9').
acted_in('Sharlto Copley', 'Elysium').
acted_in('Matt Damon', 'Elysium').
acted_in('Sharlto Copley', 'Europa Report').
acted_in('Leonardo DiCaprio', 'Don\'t Look Up').
acted_in('Jonah Hill', 'Don\'t Look Up').
acted_in('Cate Blanchett', 'Don\t Look Up').
acted_in('Adam Sandler', 'Click').
acted_in('Christopher Walken', 'Click').
acted_in('Kate Beckinsale', 'Click').
acted_in('Jonah Hill', 'Click').
acted_in('Leonardo DiCaprio', 'The Aviator').
acted_in('Cate Blanchett', 'The Aviator').
acted_in('Kate Beckinsale', 'The Aviator').
acted_in('Brad Pitt', 'Inglourious Basterds').
acted_in('Melanie Laurent', 'Inglourious Basterds').
acted_in('Michael Fassbender', 'Inglourious Basterds').
acted_in('Diane Kruger', 'Inglourious Basterds').

directed('Alejandro Gonzalez Inarritu', 'Babel').
directed('Neill Blomkamp', 'District 9').
directed('Neill Blomkamp', 'Elysium').
directed('Sebastian Cordero', 'Europa Report').
directed('Adam McKay', 'Don\'t Look Up').
directed('Frank Coraci', 'Click').
directed('Martin Scorsese', 'The Aviator').
directed('Quentin Tarantino', 'Inglourious Basterds').

released('Babel', 2006).
released('District 9', 2009).
released('Europa Report', 2013).
released('Don\'t Look Up', 2021).
released('Click', 2006).
released('The Aviator', 2004).
released('Inglourious Basterds', 2009).

I want to run a bunch of queries on it, automatically, without me having to interactively enter in the queries.我想自动运行一堆查询,而无需交互地输入查询。 When entered in interactively, some sample queries look like:当以交互方式输入时,一些示例查询如下所示:

?- released(Movie, 2009), directed(Director, Movie).
Movie = 'District 9',
Director = 'Neill Blomkamp' ;
Movie = 'Inglourious Basterds',
Director = 'Quentin Tarantino'.

?- acted_in(Actor, 'Click'), acted_in(Actor, 'The Aviator').
Actor = 'Kate Beckinsale' ;
false.

?- directed(Director_1, Movie), directed(Director_2, Movie), \+ Director_1 = Director_2.
false.

Since these are ran interactively, I know what queries were asked with what results.由于这些是交互式运行的,我知道什么查询被问到什么结果。 When I run them programmatically, I basically want the exact same output but with the query that produced each result printed above it.当我以编程方式运行它们时,我基本上想要完全相同的 output 但生成每个结果的查询打印在它上面。 I've seen some things with the initialization/1 directive after searching, but I wasn't for sure how to list the queries and then get them printed out with their results.搜索后,我已经看到了有关initialization/1指令的一些内容,但我不确定如何列出查询,然后将它们与结果一起打印出来。 I am still new to Prolog and would like to continue along the current book I'm going through without getting too bogged down with this diversion, although the diversion will help going through the book.我仍然是 Prolog 的新手,并且想继续阅读我正在阅读的当前书籍,而不会因这种转移而陷入困境,尽管转移将有助于阅读本书。 I'd just like a simple thing I can implement so that I can run a list of queries when the file is loaded, the queries themselves are printed out followed by their results.我只是想要一个我可以实现的简单的东西,这样我就可以在加载文件时运行一个查询列表,查询本身被打印出来,然后是它们的结果。

Thanks!谢谢!

One way to achieve this is to define these two helper methods:实现此目的的一种方法是定义这两个辅助方法:

% Obtain one possible substitution ("Result") for Query
get_result(Query, Result) :-
    term_string(Term, Query, [variable_names(VariableNames)]),
    Term,
    Result = VariableNames.

% Find and print all substitutions for Query, fail if empty
log_query(Query) :-
    format("Evaluating: ~w ~n", [Query]),
    findall(Result, get_result(Query, Result), Results),
    not(length(Results,0)),
    writeln(Results).

With this we can define a predicate to run our queries:有了这个,我们可以定义一个谓词来运行我们的查询:

main :-
    log_query("released(Movie, 2009), directed(Director, Movie)."),
    log_query("acted_in(Actor, 'Click'), acted_in(Actor, 'The Aviator')."),
    log_query("directed(Director_1, Movie), directed(Director_2, Movie), \\+ Director_1 = Director_2.").

And then to add this clause to run this predicate on initialization:然后添加此子句以在初始化时运行此谓词:

:- initialization main.

This will log the following at the start of a session:这将在 session 的开头记录以下内容:

Evaluating: released(Movie, 2009), directed(Director, Movie). 
[[Movie=District 9,Director=Neill Blomkamp],[Movie=Inglourious Basterds,Director=Quentin Tarantino]]
Evaluating: acted_in(Actor, 'Click'), acted_in(Actor, 'The Aviator'). 
[[Actor=Kate Beckinsale]]
Evaluating: directed(Director_1, Movie), directed(Director_2, Movie), \+ Director_1 = Director_2. 
Warning: Initialization goal failed

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM