如何从命令行运行SWI-Prolog?

时间:2014-08-23 22:53:22

标签: shell command-line prolog executable swi-prolog

有没有办法像这样创建名为hello.pl的prolog脚本:

#!/usr/local/bin/swipl -q -s -t main

main:-
  write('Hello World\n').

能够像这样从终端运行吗?

$ hello.pl
Hello World
$

当我这样做时,它给了我这个:

hello.pl: line 3: main:-: command not found
hello.pl: line 4: syntax error near unexpected token `'Hello World\n''
hello.pl: line 4: `  write('Hello World\n').'

我可以通过在命令行上写这个来使它工作:

$ swipl -q -f hello.pl -t main
Hello World
$

但有没有办法将直接脚本作为可执行文件运行?

修改

尚未能让它发挥作用。以下是@Boris在其答案中的评论中提出的输出:

$ ls -l
total 8
-rwxr-xr-x  1 viatropos  staff  235 Aug 26 20:28 example.pl
$ cat example.pl
#!/usr/local/bin/swipl

:- set_prolog_flag(verbose, silent).

:- initialization main.

main :-
    format('Example script~n'),
    current_prolog_flag(argv, Argv),
    format('Called with ~q~n', [Argv]),
    halt.
main :-
    halt(1).
$ which swipl
/usr/local/bin/swipl
$ swipl --version
SWI-Prolog version 6.6.6 for x86_64-darwin13.1.0
$ ./example.pl
./example.pl: line 3: syntax error near unexpected token `('
./example.pl: line 3: `:- set_prolog_flag(verbose, silent).'
$

我使用的是Mac OSX 10.9.2,并通过brew install swi-prolog --with-libarchive

安装了swipl和自制软件

3 个答案:

答案 0 :(得分:11)

ISO指令:initialization。这应该有用。

:- initialization main.

main :-
  write('Hello World\n').

编辑抱歉,我跳过了最有趣的细节。这是一个示例脚本,假设保存在〜/ test / main.pl

#!/home/carlo/bin/swipl -f -q

:- initialization main.

main :-
  current_prolog_flag(argv, Argv),
  format('Hello World, argv:~w\n', [Argv]),
  halt(0).

并使用

实现可执行文件
chmod +x ~/test/main.pl

然后我得到

~$ ~/test/main.pl
Hello World, argv:[]

~$ ~/test/main.pl as,dnj asdl
Hello World, argv:[as,dnj,asdl]

在脚本main.pl中,我使用了从源代码构建而没有管理员权限的swipl路径。 SWI-Prolog构建过程将bin和lib放在〜/ bin和〜/ lib

注意:-f标志禁用加载初始化〜/ .plrc,这可能是必要的,以便对执行进行更严格的控制......

我目前不确定文档页面是否与当前的SW状态保持同步。从some mailing list message开始,我自己努力重用thea,似乎最近命令行标志发生了变化......

答案 1 :(得分:5)

另一个答案或多或少是正确的,但是,它的工作原理可能取决于您的操作系统。最容易实现的方法是:

$ cat example.pl
#!/path/to/your/swipl

:- set_prolog_flag(verbose, silent).

:- initialization main.

main :-
    format('Example script~n'),
    current_prolog_flag(argv, Argv),
    format('Called with ~q~n', [Argv]),
    halt.
main :-
    halt(1).

这里的不同之处在于,除了通向swipl的路径之外,shebang线上没有任何东西。其他一切都是使用指令完成的。在我的操作系统上,仅有效

$ chmod u+x example.pl
$ example.pl foo bar baz
Example script
Called with [foo,bar,baz]

修改

完全删除shebang行可能更干净,而是从命令行运行:

$ swipl -s example.pl -- foo bar baz
Example script
Called with [foo,bar,baz]

同样,使用指令将main/0设置为初始化目标可以使您不必在命令行上显式执行此操作。另一方面,从命令行调用swipl可让您的操作系统找到可执行文件的位置,而不是在脚本中对此信息进行硬编码。

答案 2 :(得分:0)

您可以使用initialization/2

#!/path/to/swipl -q

:- initialization(main, program).

main :-
    write("Hello"), nl,
    halt.

理论上:

  • -q--quiet)用于禁止显示所有信息性消息,包括源自SWI-Prolog初始化文件(~/.swiplrc)的信息性消息。可以改用:- set_prolog_flag(verbose, silent).,但不会抑制来自初始化文件的信息性消息。

  • :- initialization(main, program).-program导致Prolog在main失败或遇到异常时以错误代码退出,而不是停留在REPL中。

  • halt-退出代码为0的程序。

以上假设您希望在运行程序之前加载初始化文件(~/.swipl)。如果您不想加载初始化文件,请使用#!/path/to/swipl -f -q作为shebang。这使脚本启动速度更快。

(另外,请确保在运行脚本(chmod +x hello.pl)之前设置可执行位(./hello.pl