我在SWI-Prolog下开发,但我的目标是Erlog(https://github.com/rvirding/erlog)。我需要一种方法来使用非标准的Prolog语法。 有没有办法编写SWI编译器忽略的prolog代码,即使其不可见。
以下示例如何:
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})).
我在想是否有一种方法可让SWI跳过这一点,而我还有另一项声明无效。
do_stuff(_,_).
一个选项可能是对它进行注释,然后在Erlog中运行之前使用解析器删除注释,但这看起来很麻烦。
任何其他想法。
==
is_dialect(swi) :- catch(current_prolog_flag(dialect, swi), _, fail).
:- if(is_dialect(swi)).
do_stuff(_,_).
:- else.
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})).
:- endif.
语法错误:操作员期望
答案 0 :(得分:3)
我使用这个成语来保持代码在不同的实现中运行
:- if(swi).
gen_hash_lin_probe(Key, HashTable, Value) :-
arg(_, HashTable, E),
nonvar(E),
E = Key-Value.
:- elif(yap).
gen_hash_lin_probe(Key, HashTable, Value) :-
HashTable =.. [htlp|Args],
nth1(_, Args, E),
nonvar(E),
E = Key-Value.
:- endif.
其中从该模块导入谓词swi / 0或yap / 0(prolog_impl)
:- module(prolog_impl, [swi/0, yap/0, prolog_impl/1]).
swi :- prolog_impl(swi).
yap :- prolog_impl(yap).
prolog_impl(K) :-
F =.. [K,_,_,_,_],
current_prolog_flag(version_data, F).
答案 1 :(得分:3)
这个答案部分基于 @Capelli's answer以及您对候选人解决方案的评论。
我们提出了一种不同的方式。 按照点一步一步......
首先,我们采用以下简化和缩短的代码段。
:- if(true). p(3). :- elif(false). p(4+3). :- endif.
在上面的示例中,我们可以看到永远不会采用“else”分支 那么......我们原则上可以将任意文本和二进制数据放在那里吗?
:- if(true). p(3). :- elif(false). p (4);;[ p()) :- endif.
нет!在(重新)加载时,我们得到:⚠语法错误:操作员期望
TIL,elif
和endif
之间的所有部分都必须是有效的Prolog文本。
让我们尝试一些不同的东西,这些东西受到你使用的短语的启发,特别是:“[...]使用非标准的Prolog语法代码,这些代码将被忽视[...] make它看不见[...]“
对我来说,短语“非标准语法”表示可能会引入新的运算符(或旧的运算符重新定义):
:- op(500,xfx,=>). :- if(true). p(2). :- elif(false). p(3 => 3). :- endif.
考虑以下变化:
:- if(true). p(2). :- elif(false). :- op(500,xfx,=>). % is moving the `op/3` here ok? p(3 => 3). :- endif.
нет!在(重新)加载后,我们得到:⚠来自[...]的未终止条件编译
还有另一种方式!我们可以通过插入一个特殊用途的end_of_file
事实来告诉Prolog文本读者忽略end_of_file.
之后的所有内容
我们这样使用它:
% snip_at_end.pl xxx1. xxx2. end_of_file. xxx3. :- op (500, xfx,eat). % broken syntax (pt.1) 1 ]][[ v % broken syntax (pt.2)
使用SICStus Prolog进行简单测试:
$ sicstus
SICStus 4.3.2 (x86_64-linux-glibc2.12): Fri May 8 01:05:09 PDT 2015
[... License information ...]
| ?- compile(snip_at_end).
% compiling /home/stefan/prolog/snip_at_end.pl...
% compiled /home/stefan/prolog/snip_at_end.pl in module user, 40 msec 400672 bytes
yes
| ?- xxx1.
yes
| ?- xxx2.
yes
| ?- xxx3.
! Existence error in user:xxx3/0
! procedure user:xxx3/0 does not exist
! goal: user:xxx3
希望这有帮助!如果我的答案适合你的问题,我很好奇/感兴趣:)
答案 2 :(得分:3)
"其他&#34>缺少一个右括号。分支。
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})). % BAD
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt}))). % OK!
只需计算左括号的数量即可。当达到.
(期间,全步)时,期初与期末的差额必须精确为零。
希望有所帮助!