【问题标题】:How to you list Prolog queries and then print each query and its result(s) programmatically?如何列出 Prolog 查询,然后以编程方式打印每个查询及其结果?
【发布时间】:2021-12-31 07:59:18
【问题描述】:

我有一个名为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).

我想自动运行一堆查询,而无需我以交互方式输入查询。以交互方式输入时,一些示例查询如下所示:

?- 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.

由于这些是交互式运行的,因此我知道询问了哪些查询并得出了哪些结果。当我以编程方式运行它们时,我基本上想要完全相同的输出,但生成每个结果的查询打印在它上面。我在搜索后看到了一些使用 initialization/1 指令的东西,但我不确定如何列出查询,然后将它们与结果一起打印出来。我仍然是 Prolog 的新手,并希望继续阅读我正在阅读的当前书籍,而不会因这种转移而陷入困境,尽管转移将有助于阅读这本书。我只是想要一个我可以实现的简单的东西,这样我就可以在加载文件时运行一个查询列表,查询本身被打印出来,然后是它们的结果。

谢谢!

【问题讨论】:

    标签: prolog swi-prolog


    【解决方案1】:

    实现这一点的一种方法是定义这两个辅助方法:

    % 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).
    

    有了这个,我们可以定义一个谓词来运行我们的查询:

    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.").
    

    然后在初始化时添加这个子句来运行这个谓词:

    :- initialization main.
    

    这将在会话开始时记录以下内容:

    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
    

    【讨论】:

    • 太棒了!谢谢!但是,对于(预期)失败的查询,我收到了警告Initialization goal failed。所以我简单地删除了not(length(Results, 0)) 行,现在它可以完美运行(只为失败的查询返回[],这很好)。我还在每个log_query 之前添加了类似write("1) "), 的内容。再次感谢!这正是我一直在寻找的,并且真正让我前进。
    • 我修改的 log_query 谓词,为了完整起见:% Find and print all substitutions for Query log_query(Number, Query) :- format("~w) Evaluating: ~w~n", [Number, Query]), findall(Result, get_result(Query, Result), Results), writeln(Results), nl. 然后被称为:log_query(1, "released(Movie, 2009), directed(Director, Movie).")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2021-09-09
    相关资源
    最近更新 更多