如何输出结果到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
当然你可以想出你自己的开箱即用的方法,我鼓励这样做。
我有一个 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
当然你可以想出你自己的开箱即用的方法,我鼓励这样做。