Skip/pass 非标准序言代码
Skip/pass non-standard prolog code
我在 SWI-Prolog 下开发,但我的目标是 Erlog (https://github.com/rvirding/erlog)。我需要一种使用非标准 Prolog 语法的方法。
有没有一种方法可以编写将被 SWI 编译器忽略的序言代码,即使其不可见。
这是一个例子,它看起来像什么:
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.
语法错误:应为运算符
我使用这个习惯用法来保持代码 运行 在不同的实现中
:- 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).
此答案部分基于
以及您对他的候选解决方案的评论。
我们提出了一种不同的方式。 循序渐进...
首先,我们采用以下经过简化和缩短的代码段。
:- if(true). p(3).
:- elif(false). p(4+3).
:- endif.
在上面的示例中,我们可以看到 "else" 分支从未被采用。
那么...原则上,我们可以将任意文本和二进制数据放在那里吗?
:- if(true). p(3).
:- elif(false). p (4);;[ p())
:- endif.
恩!在(重新)加载时,我们得到:⚠ 语法错误:预期运算符
直到 elif
和 endif
之间的所有部分都必须是有效的 Prolog 文本。
让我们尝试一些不同的东西,它受到您使用的短语的启发,特别是:“[...] 使用非标准的 Prolog 语法 [...] 将被忽略的代码 [。 ..] 使其不可见 [...]"
对我来说,短语 "non-standard syntax" 表示可能会引入新的运算符(或重新定义旧运算符):
:- 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 文本 reader 忽略 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
希望对您有所帮助!如果我的回答符合您的问题,我很好奇/感兴趣:)
"else" 分支中缺少一个右括号。
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!
简单数一下左括号的个数。当达到 .
(周期,整步)时,打开与关闭的差异计数必须正好为零。
希望对您有所帮助!
我在 SWI-Prolog 下开发,但我的目标是 Erlog (https://github.com/rvirding/erlog)。我需要一种使用非标准 Prolog 语法的方法。 有没有一种方法可以编写将被 SWI 编译器忽略的序言代码,即使其不可见。
这是一个例子,它看起来像什么:
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.
语法错误:应为运算符
我使用这个习惯用法来保持代码 运行 在不同的实现中
:- 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).
此答案部分基于
我们提出了一种不同的方式。 循序渐进...
首先,我们采用以下经过简化和缩短的代码段。
:- if(true). p(3). :- elif(false). p(4+3). :- endif.
在上面的示例中,我们可以看到 "else" 分支从未被采用。
那么...原则上,我们可以将任意文本和二进制数据放在那里吗?:- if(true). p(3). :- elif(false). p (4);;[ p()) :- endif.
恩!在(重新)加载时,我们得到:⚠ 语法错误:预期运算符
直到
elif
和endif
之间的所有部分都必须是有效的 Prolog 文本。让我们尝试一些不同的东西,它受到您使用的短语的启发,特别是:“[...] 使用非标准的 Prolog 语法 [...] 将被忽略的代码 [。 ..] 使其不可见 [...]"
对我来说,短语 "non-standard syntax" 表示可能会引入新的运算符(或重新定义旧运算符):
:- 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 文本 reader 忽略 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
希望对您有所帮助!如果我的回答符合您的问题,我很好奇/感兴趣:)
"else" 分支中缺少一个右括号。
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!
简单数一下左括号的个数。当达到 .
(周期,整步)时,打开与关闭的差异计数必须正好为零。
希望对您有所帮助!