如何输出结果到shell?

How to output result to shell?

我有一个 shell 脚本,script.sh:

#!/bin/bash
FIRST_ARGUMENT=""

swipl -s script4.pl $FIRST_ARGUMENT

prolog.pl:

:- initialization main.

query :-
        current_prolog_flag(argv, Argv),
        concat_atom(Argv, ' ', Atom),
        read_term_from_atom(Atom, Term, []),
        call(Term).

main :-
        catch(query, E, (print_message(error, E), fail)),
        halt.
main :-
        halt(1).

b(a).
a(c, d) :- writeln('I was called!').

现在,如果我从命令行调用脚本:

sh s.sh 'a(c,d).'

会输出"I was called!".

但是如果我 运行 查询除了 yes/no 答案:

sh s.sh 'b(a).'

它只告诉我:script4.pl compiled 0.00 sec, 7 clauses。当我想要的是 "true" 因为找到了与输入匹配的事实。我怎样才能得到结果?

我想从 Rake(Ruby 派生)查询我的 Prolog 程序。我想脚本是一种简单的方法来做到这一点,但也许它不够强大?

一种简单但粗略的方法是将 writeln(true)writeln(false) 分别添加到 main/0 的每个成功和失败子句中:

main :- catch(query, E, (print_message(error, E), fail)),
        writeln(true),
        halt.
main :- writeln(false),
        halt(1).

虽然我确定有更好的解决方案...

通常,shell 脚本 return 成功时为零,失败时为非零整数,解释为错误代码。因此,您可以使用标准 halt/1 谓词来 return 零或例如一个取决于您的查询,分别是成功还是失败。你已经这样做了,但你可以用类似的东西让它更清楚一点:

main :-
    (   query ->
        halt(0)
    ;   halt(1)
    ).

如果查询可能会抛出异常,请使用标准 catch/3 谓词将其包装:

main :-
    (   catch(query, _, fail) ->
        halt(0)
    ;   halt(1)
    ).

您也可以使用异常来选择退出值:

main :-
    (   catch(query, Error, error_handler(Error)) ->
        halt(0)
    ;   halt(1)
    ).

error_handler(error1) :- halt(2).
error_handler(error2) :- halt(3).
...

在这种情况下,零表示成功,一表示失败,任何其他整数表示相应的错误。

由于您希望 prolog 生成的输出通常严格在​​其交互式 shell 中完成,因此这是需要某种类型的 crude 实现的事情之一。这个特别的可能被认为是极端的,但它确实有效

#!/bin/bash
FIRST_ARGUMENT=""

swipl -l script4.pl $FIRST_ARGUMENT',halt(n).' 2>&1 | sed 's/ERROR: halt\/1.*/True/g'

结果:

$ sh s.sh 'b(a)'
True

当然你可以想出你自己的开箱即用的方法,我鼓励这样做。