Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何将结果输出到shell?_Macos_Prolog_Swi Prolog_Prologscript - Fatal编程技术网

Macos 如何将结果输出到shell?

Macos 如何将结果输出到shell?,macos,prolog,swi-prolog,prologscript,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,

我有一个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).'
将输出
“我被呼叫!”

但是,如果我运行一个查询(回答是/否除外):

sh s.sh 'b(a).'
它告诉我的是:
script4.pl编译0.00秒,7个子句。当我想要的是“真”时,因为找到了与输入匹配的事实。我怎样才能得到结果


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

一种简单、公认粗糙的方法是将
writeln(true)
writeln(false)
分别添加到
main/0
的每个success和fail子句中:

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

尽管我确信有更好的解决方案……

通常,shell脚本在成功时返回零,在失败时返回非零的整数,解释为错误代码。因此,您可以使用标准的
halt/1
谓词分别根据查询的成功与否返回0或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).
...

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

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

#!/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

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

您需要决定是否真的需要将程序作为脚本调用,而不是使用顶层(解释器)。除了批量文本处理(?),几乎没有理由使用脚本而不是顶层脚本。也许我可以做些什么来改善这一点。您可以使用SWI Prolog命令行选项
--quiet
-q
,使有关编译文件所需时间和其中子句数量的信息静音。尝试此操作的任何人都要密切注意此答案。请注意,参数
b(a)
没有“.”,因为现在这是shell命令的一部分。虽然I'L'I的方法很有趣,但我使用了这个方法,因为它可以在windows和mac上工作。这两种方法我都需要。这个方法看起来更一般,在有限的意义上,它让Prolog代码决定生成哪种类型的输出。相反,I'L'I的方法似乎在unix方面提供了某种保证,确保了shell脚本的某些输出。我认为,重要的一点是,输出“true.”和“false.”只在顶层对Prolog有明确的意义。当我们使用Prolog程序作为链接到其他程序的可执行文件时,我们只希望它们输出我们需要的任何类型的数据。“使用Prolog来验证事实是一个非常特殊的例子。”一位心理学家说得很好——我的答案中的方法是我一时兴起想出的。虽然正如P.Brian.Mackey所说,这很有趣,但我认为使用一个能够处理prolog本身的解决方案应该是首选。看到每个人的答案都有这样的想法真是太好了,因为它确实允许一个人走出以前可能做过的事情的领域。@l'l'l同意!看到各种不同的方法和解决方案真的很有帮助,让人耳目一新。让我更好地了解这些工具的灵活性。