如何将结果输出到shell?

时间:2015-02-21 20:34:19

标签: macos prolog swi-prolog prologscript

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

#!/bin/bash
FIRST_ARGUMENT="$1"

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!"

但如果我运行查询,除了是/否答案:

sh s.sh 'b(a).'

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

我想从Rake(Ruby派生物)查询我的Prolog程序。我想一个脚本是一种简单的方法,但它可能不够强大?

3 个答案:

答案 0 :(得分:2)

由于您希望prolog生成的内容的输出通常严格地在其交互式shell中完成,因此这需要某种类型的crude实现。这个特殊的可能会被考虑在极端, ,但它确实有用

#!/bin/bash
FIRST_ARGUMENT="$1"

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

结果:

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

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

答案 1 :(得分:1)

一种简单的,粗俗的方式是分别为writeln(true)的每个成功和失败条款添加writeln(false)main/0

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

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

答案 2 :(得分:1)

通常,shell脚本在成功时返回零,而非零的整数在失败时解释为错误代码。因此,您可以使用标准halt/1谓词返回零或例如一个取决于您的查询,分别成功或失败。你已经在做了,但你可以通过以下方式让它更清晰:

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

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