Как запустить SWI-Prolog из командной строки?
Есть ли способ создать пролог script, называемый hello.pl
следующим образом:
#!/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
$
Но есть ли способ просто запустить прямой script как исполняемый файл вместо этого?
Edit
Пока еще не удалось заставить это работать. Вот вывод из команд, которые @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 и устанавливаю swipl с homebrew через brew install swi-prolog --with-libarchive
Ответы
Ответ 1
Директива ISO: initialization. Это должно работать.
:- initialization main.
main :-
write('Hello World\n').
Извините, я пропустил самые интересные детали. Вот пример script, скажем, сохраненный в ~/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]
В script main.pl
я использовал путь swipl, который возникает из-за создания из источника без прав администратора. Процесс сборки SWI-Prolog помещает bin и lib в ~/bin и ~/lib
Примечание: флаг -f отключает загрузку инициализации ~/.plrc, и это может потребоваться, чтобы получить более строгий контроль над выполнением...
В настоящее время я не уверен, что страница документации обновлена с текущим статусом SW. Из сообщения о рассылке и моих собственных попыток повторного использования thea кажется, что флаги командной строки изменены в последнее время...
Ответ 2
Другой ответ более или менее правильный, однако, как это работает, может зависеть от вашей ОС. Самый портативный способ сделать это - это:
$ 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).
Разница здесь в том, что на линии shebang нет ничего, кроме пути к swipl. Все остальное делается с помощью директив. В моей ОС работает только!
$ 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
из командной строки, с другой стороны, позволяет вашей ОС находить, где исполняемый файл, вместо жесткого кодирования этой информации в script.
Ответ 3
Вы можете использовать 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
в качестве шебанга. Это заставляет скрипт запускаться быстрее.
(Также обязательно установите исполняемый бит (chmod +x hello.pl
) перед запуском скрипта (./hello.pl
))