Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog 第/2条中未充分实例化参数_Prolog - Fatal编程技术网

Prolog 第/2条中未充分实例化参数

Prolog 第/2条中未充分实例化参数,prolog,Prolog,我正试图为prolog中的统一编写一个简单的元解释器,这就是我目前得到的 unify(A,B):-var(A),A=B. unify(A,B):-nonvar(A),var(B),B=A. unify(A,B):-compound(A),compound(B),A=..[F|ArgsA],B=..[F|ArgsB],unify_args(ArgsA,ArgsB). unify_args([A|TA],[B|TB]):-unify(A,B),unify_args(TA,TB). unify_ar

我正试图为prolog中的统一编写一个简单的元解释器,这就是我目前得到的

unify(A,B):-var(A),A=B.
unify(A,B):-nonvar(A),var(B),B=A.
unify(A,B):-compound(A),compound(B),A=..[F|ArgsA],B=..[F|ArgsB],unify_args(ArgsA,ArgsB).

unify_args([A|TA],[B|TB]):-unify(A,B),unify_args(TA,TB).
unify_args([],[]).


meta(true).
meta((A,B)):- meta(A),meta(B).
meta(C):-clause(H,B), unify(H,C), meta(B).
我遇到的问题是,当我试图统一两个变量时

meta((A,B)). 
我得到了正确的结果

A = B, B = true .
但当我尝试统一其他任何东西时,例如

meta((a,a)).
甚至是一台计算机,我都会遇到以下错误:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [12] clause(_4306,_4308)
ERROR:   [11] meta(a) at path_redacted/unify1.pl:22
ERROR:   [10] meta((a,a)) at path_redacted/unify1.pl:21
ERROR:    [9] <user>
错误:参数未充分实例化
错误:在:
错误:[12]子句(_4306,_4308)
错误:[11]元(a)位于路径_已编辑/统一1。pl:22
路径_处的错误:[10]元((a,a))已编辑/统一1.pl:21
错误:[9]
我不明白为什么第/2条在这种特殊情况下需要实例化的论点,或者我遗漏了其他东西


感谢您的帮助

正如威尔·内斯在评论中指出的那样,
子句/2
需要实例化
标题

如前所述,元解释器尝试枚举程序中所有谓词的所有子句,以找到与目标术语
C
统一的子句。您必须将此限制为仅枚举与
C
匹配的子句。一种方法是直接调用
子句(C,Body)
。我猜你是想避免这种情况,因为这会欺骗你,因为你会为自己统一

另一种方法是复制
C
的函子,但不复制其参数。您可以使用此副本查找感兴趣谓词的子句,但您仍然可以自己进行统一

以下是您如何进行这种“骨架”复制:

在元解释器的上下文中,类似这样的内容可以让您更接近您想要的内容:

meta(Goal) :-
    functor(Goal, Functor, Arity),
    functor(Head, Functor, Arity),
    clause(Head, Body),
    unify(Head, Goal),
    meta(Body).
例如,使用此示例程序:

f(x).
g(y).

fg(X, Y) :-
    f(X),
    g(Y).
我们得到:

?- meta(fg(X, Y)).
X = x,
Y = y ;
ERROR: No permission to access private_procedure `true/0'
ERROR: In:
ERROR:   [12] clause(true,_2750)
...

正确地找到了解决方案,但回溯进一步的答案会尝试访问
true
的子句。SWI Prolog不允许这样做。在使元解释器的子句互斥时,您必须更加小心。您可能需要进行剪切。

正如Ness在评论中指出的那样,
子句/2
需要实例化
标题

如前所述,元解释器尝试枚举程序中所有谓词的所有子句,以找到与目标术语
C
统一的子句。您必须将此限制为仅枚举与
C
匹配的子句。一种方法是直接调用
子句(C,Body)
。我猜你是想避免这种情况,因为这会欺骗你,因为你会为自己统一

另一种方法是复制
C
的函子,但不复制其参数。您可以使用此副本查找感兴趣谓词的子句,但您仍然可以自己进行统一

以下是您如何进行这种“骨架”复制:

在元解释器的上下文中,类似这样的内容可以让您更接近您想要的内容:

meta(Goal) :-
    functor(Goal, Functor, Arity),
    functor(Head, Functor, Arity),
    clause(Head, Body),
    unify(Head, Goal),
    meta(Body).
例如,使用此示例程序:

f(x).
g(y).

fg(X, Y) :-
    f(X),
    g(Y).
我们得到:

?- meta(fg(X, Y)).
X = x,
Y = y ;
ERROR: No permission to access private_procedure `true/0'
ERROR: In:
ERROR:   [12] clause(true,_2750)
...
正确地找到了解决方案,但回溯进一步的答案会尝试访问
true
的子句。SWI Prolog不允许这样做。在使元解释器的子句互斥时,您必须更加小心。您可能需要进行切割。

请参阅。它总是需要它的第一个参数,如在
+
模式中:表示“
…此标志表示
+
”请参阅。它总是需要它的第一个参数,如在
+
模式中:表示“
…此标志表示
+