如何在ISO Prolog中定义一个(元逻辑)谓词,用于在线性时间内运行的两个变量列表的交集?变量可以按任何确定的顺序出现.没有像变量"年龄"这样的实现依赖属性必须影响结果.
与之类似library(ordsets),我们称之为关系varset_intersection(As, Bs, As_cap_Bs).
?- varset_intersection([A,B], [C,D], []).
true.
?-varset_intersection([A,B], [B,A], []).
false.
?- varset_intersection([A,B,C], [C,A,D], Inter).
Inter = [A,C].
or
Inter = [C,A].
?- varset_intersection([A,B],[A,B],[A,C]).
B = C
or
A = B, A = C
?- varset_intersection([A,B,C],[A,B],[A,C]).
idem
Run Code Online (Sandbox Code Playgroud)
也就是说,第三个参数是输出参数,它与前两个参数的交集相结合.
请参阅当前ISO标准(ISO/IEC 13211-1:1995,包括Cor.2)的内置插件列表.
(请注意,几年前我在另一个问题中回答了这个问题.然而,谷歌仍然隐藏着这个问题.)
我想知道如何在Prolog中添加错误检查.例如,我有一个程序可以找到一个列表有多长:
listlen([],0).
listlen([_|T],N) :-
listlen(T,X),
N is X+1.
Run Code Online (Sandbox Code Playgroud)
当它发生时,我如何打印出"第一个参数必须是列表"这样的错误?
所以我被告知一个特定的谓词必须在 +,+ 模式下工作。这在 Prolog 中是什么意思?
我有一个手动制作的DCG规则来选择单个单词的惯用语.DCG规则如下:
seq(cons(X,Y), I, O) :- noun(X, I, H), seq(Y, H, O), \+ noun(_, I, O).
seq(X) --> noun(X).
Run Code Online (Sandbox Code Playgroud)
第一个子句是手动制作的,因为它(:-)/2是用来代替的(-->)/2.我可以用一些使用标准DCG的子句替换这个手工制作的子句吗?
最好的祝福
PS:这是一些测试数据:
noun(n1) --> ['trojan'].
noun(n2) --> ['horse'].
noun(n3) --> ['trojan', 'horse'].
noun(n4) --> ['war'].
Run Code Online (Sandbox Code Playgroud)
以下是一些测试用例,重要的测试用例是第一个测试用例,因为它只提供n3而不是cons(n1,n2).第一个测试用例的行为是特别需要的:
?- phrase(seq(X),['trojan','horse']).
X = n3 ;
No
?- phrase(seq(X),['war','horse']).
X = cons(n4,n2) ;
No
?- phrase(seq(X),['trojan','war']).
X = cons(n1,n4) ;
No
Run Code Online (Sandbox Code Playgroud) 我意识到这会有限制,但是有没有一种合理的方法可以在 Prolog 代码中放入条件指令,以便在 GNU 或 SWI 中合理地工作?我至少在考虑最简单的情况,即sumlistSWI 和sum_listGNU中的内置谓词在拼写上彼此不匹配。或者 SWI 有assert但 GNU 没有。所以最好有这样的东西:
:- if($SWI).
SWI version of stuff
:- else.
GNU version of stuff
:- endif.
Run Code Online (Sandbox Code Playgroud)
或者干脆:
:- if(not_a_builtin(sumlist))
sumlist(L, S) :- sum_list(L, S).
:- endif.
Run Code Online (Sandbox Code Playgroud)
或者什么不是。两种语言中都存在条件指令,但似乎只是提供了做这种事情所需的条件。我可能错过了手动搜索没有出现的东西。
变体谓词的这两个实现之间是否存在逻辑差异?
variant1(X,Y) :-
subsumes_term(X,Y),
subsumes_term(Y,X).
variant2(X_,Y_) :-
copy_term(X_,X),
copy_term(Y_,Y),
numbervars(X, 0, N),
numbervars(Y, 0, N),
X == Y.
Run Code Online (Sandbox Code Playgroud) 如何添加一个函数(例如,汉明重量)并在右侧出现的表达式中使用它是一些(is)/2目标?
像goal_expansion或term_expansion这样的东西可以帮助吗?
我承认这不是一个很大的功能,但它可以提高我的一些Prolog程序的可读性.
编写自定义(is)/2谓词(实现自定义表达式求值程序)是可行的,但我希望将运行时开销保持在较低水平,因为在这种情况下我不想牺牲运行时开销的可读性.
在最近的一个问题(如何在ISO Prolog中定义(和命名)相应的安全术语比较谓词?)@ false要求实现术语排序谓词lt/2,ISO内置的变体(@<)/2.
真值lt(T1,T2)是要T1和任意变量绑定的稳定T2.
在各种答案中,提出了不同的实现(基于隐式/显式术语遍历).在评论中提出了一些警告和提示,反例也是如此.
所以我的问题是:如何测试候选实施?有些蛮力的做法?还是更聪明的东西?
无论如何,请分享您的自动测试机器lt/2!这是为了更大的利益!
我通过SWI-Prolog学到了很难的方法,Prolog指令的位置set_prolog_flag在源代码文件中很重要.
我发现有关使用指令加载源代码文件的唯一文档是在加载Prolog源文件中
指令是编译器的指令.指令用于设置(谓词)属性(请参阅第4.15节),设置标志(请参阅set_prolog_flag/2)和加载文件(本节).指令是形式的术语: - <term>.
是否有SWI-Prolog的文档,其中包含源代码的加载,如果指令适用于整个文件或取决于源代码文件中的位置,则会注意到这些文档的加载?
或者是从源代码文件加载的所有行只是简单地将语句播放到顶层并且位置始终很重要?
在Prolog中使用明确的句子语法(DCG)时,已知DCG要求输入是字符代码列表,例如
?- string_codes("abc123",Cs).
Cs = [97, 98, 99, 49, 50, 51].
Run Code Online (Sandbox Code Playgroud)
并在源代码文件中使用以下DCG规则并加载到顶级
digit(0) --> "0".
Run Code Online (Sandbox Code Playgroud)
DCG可以使用
?- string_codes("0",Cs),phrase(digit(D),Cs,R).
Cs = [48],
D = 0,
R = []
Run Code Online (Sandbox Code Playgroud)
现在,为了更容易使用DCG而不必使用string_codesProlog指令
:- set_prolog_flag(double_quotes, chars).
Run Code Online (Sandbox Code Playgroud)
可以在源代码文件中使用,并在源代码文件中使用以下DCG规则并加载到顶级
digit(0) --> "0".
Run Code Online (Sandbox Code Playgroud)
DCG可以使用
?- phrase(digit(D),"0",R).
D = 0,
R = [].
Run Code Online (Sandbox Code Playgroud)
事实证明,if set_prolog_flag出现在 DCG规则之前然后跳过string_codes工作,但如果set_prolog_flag出现在 DCG规则之后则跳过string_codes失败.
:- set_prolog_flag(double_quotes, chars). …Run Code Online (Sandbox Code Playgroud) iso-prolog ×10
prolog ×10
dcg ×2
directive ×1
expression ×1
gnu-prolog ×1
list ×1
portability ×1
swi-prolog ×1
testing ×1