我正在阅读Prolog教程.它告诉我可以通过输入以下命令加载其他prolog文件:
[filename].
Run Code Online (Sandbox Code Playgroud)
但每次我试着这样做
ERROR: load_files/2: Arguments are not sufficiently instantiated.
Run Code Online (Sandbox Code Playgroud)
该文件与我正在工作的目录位于同一目录中.
这是整个查询和错误的副本:
12 ?- [KB5].
ERROR: load_files/2: Arguments are not sufficiently instantiated
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我想读取纯文本文件并将谓词应用于每一行(谓词包含write输出的内容).我该怎么办?
任何人都可以告诉我如何访问prolog列表中的特定成员?比方说,我需要访问传递给规则的列表的第3或第4个元素?
我试图找出如何连接两个原子:
A = 'my ',
B = 'atom',
Run Code Online (Sandbox Code Playgroud)
如何连接这两个原子,结果如下:
'my atom'
Run Code Online (Sandbox Code Playgroud)
?
ISO-Prolog(ISO/IEC 13211-1:1995,包括Cor.1:2007,Cor.2:2012)提供了以下用于测试术语类型的内置谓词:
8.3型式试验
1 var/1.2原子/ 1.3整数/ 1.4浮点/ 1.5原子/ 1.6化合物/ 1.7 nonvar/1.8号/ 1.9可赎回/ 1.10地/ 1.11 acyclic_term/1.
在这一组中有那些目的只是为了测试某种实例,即8.3.1 var/1,8.3.7 nonvar/1,8.3.10 ground/1,而那些假设长期充分实例化使得型式试验是安全的.不幸的是,它们与测试具体实例相结合.
考虑目标integer(X),其失败,如果X是一个nonvar术语,不是一个整数,并当X是一个变量.这破坏了许多理想的声明属性:
?- X = 1, integer(X).
true.
?- integer(X), X = 1.
false.
Run Code Online (Sandbox Code Playgroud)
理想情况下,第二个查询将使用某种形式的coroutining成功; 或者根据错误分类发出实例化错误1.毕竟:
7.12.2错误分类
错误根据Error_term的形式分类:
a)当
参数或其中一个组件是变量并且需要
实例化的参数或组件时,应该存在实例化错误.它有
形式instantiation_error....
请注意,实例化测试和类型测试的这种隐式组合会导致Prolog程序中的许多错误,并且也会出现在SO上.
对这种情况的快速解决方法是在内置的每个测试之前添加一个显式测试,或者详细说明
( var(T) -> throw(error(instantiation_error,_)) ; true),
integer(T), ....
Run Code Online (Sandbox Code Playgroud)
或更紧凑
functor(T, _,_),
integer(T), ....
Run Code Online (Sandbox Code Playgroud)
它甚至可以
T =.. _,
integer(T), …Run Code Online (Sandbox Code Playgroud) 考虑一个(元逻辑)谓词var_in_vars(Var, Vars),它采用变量Var和变量列表,Vars如果Var出现则成功Vars.所以我们不需要确保它Var是变量,也不Vars是变量列表.
在ISO Prolog中表达这一点的最紧凑和规范的方法是什么?以下是ISO/IEC 13211-1:1995中内置插件的概述,包括Cor.2:2012.
?- var_in_vars(V, [U,V,W]).
true.
?- var_in_vars(V, [X,Y,Z]).
false.
Run Code Online (Sandbox Code Playgroud) 如果两个唯一变量列表包含完全相同的变量,使用当前ISO标准(ISO/IEC 13211-1:1995,包括Cor.)的内置插件,如何定义测试(因此成功或失败)的元逻辑谓词. 2).
换句话说,如果一个唯一变量列表是另一个变量的排列,则谓词应该成功.与library(ordsets)此类推,我们称之为元逻辑谓词 varset_seteq(As, Bs).
请注意,与此相反ord_seteq/2,这个谓词不能简单As == Bs.
我想知道在各种Prolog实现上如何实现智能的第一个参数索引.
特别是,简单的类型测试目标,例如integer/1在"颈部"条款之后,可以有助于更好的索引.考虑:
foo(h(X),X).
foo([],nil).
foo([_|_],cons).
foo(X,Y) :- integer(X), Y = n(X).
Run Code Online (Sandbox Code Playgroud)
通过这个子句排序,我希望目标foo([],_)能够成功而不会留下任何无用的选择点.
不幸的是,SWI Prolog没有弄明白:
?- length(Xs,10),
maplist(=([]),Xs),
statistics(trailused,T1),
maplist(foo,Xs,Ys),
statistics(trailused,T2).
T1 = 5792,
T2 = 5968,
Xs = [[], [], [], [], [], [], [], [], [], []],
Ys = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] ...
Run Code Online (Sandbox Code Playgroud)
其他Prolog实现做得更好吗?
我写了一个谓词,shuffle/3它生成了两个列表的"shuffles".当第二个和第三个参数被实例化时,第一个参数变为一个列表,其中包含Left和Right的所有元素,其顺序与它们在Left和Right中的显示顺序相同.
例如:
?- shuffle(X, [1, 2], [3, 4]).
X = [1, 3, 2, 4] ;
X = [1, 3, 4, 2] ;
X = [1, 2, 3, 4] ;
X = [3, 4, 1, 2] ;
X = [3, 1, 2, 4] ;
X = [3, 1, 4, 2] ;
false.
Run Code Online (Sandbox Code Playgroud)
这是我为实现它而编写的代码:
shuffle([], [], []).
shuffle([H|R], [H|Left], Right) :- shuffle(R, Right, Left).
shuffle([H|R], Left, [H|Right]) :- shuffle(R, Right, Left).
Run Code Online (Sandbox Code Playgroud)
这种方法效果很好,甚至可以为"最常见的查询"生成合理的结果,但它无法确定任何查询,即使是所有参数都完全实例化的查询:shuffle([1, 2, 3, 4], [1, 2], [3, 4]) …
prolog ×10
iso-prolog ×3
dcg ×1
indexing ×1
io ×1
list ×1
prolog-dif ×1
swi-prolog ×1
unification ×1