Parsing Prolog为/2,参数未充分实例化

Parsing Prolog为/2,参数未充分实例化,parsing,prolog,abstract-syntax-tree,instantiation-error,Parsing,Prolog,Abstract Syntax Tree,Instantiation Error,我正在做一个作业,我为前缀符号算术语言创建了一个解析器。我需要编写一个谓词,为任何给定的值V构建一个ast(即,生成一个ast a,这样每当对a求值时,它的值都是V)。我的想法很简单: genAst(Val, Env, Ast) :- ev(Ast, Env, Val). 其中ev是求值谓词。当我运行此命令时,我在ev谓词的这一部分的标题上得到错误: ev(xer_(power(N)), Env, V) :- integer(N), V is Env^N. %THIS LIN

我正在做一个作业,我为前缀符号算术语言创建了一个解析器。我需要编写一个谓词,为任何给定的值V构建一个ast(即,生成一个ast a,这样每当对a求值时,它的值都是V)。我的想法很简单:

genAst(Val, Env, Ast) :-
   ev(Ast, Env, Val).
其中ev是求值谓词。当我运行此命令时,我在ev谓词的这一部分的标题上得到错误:

ev(xer_(power(N)), Env, V) :-
   integer(N),
   V is Env^N. %THIS LINE
其中V和N都未绑定。我正在努力想另一种优雅的方法来实现这一点,有人知道我如何让prolog为这两个变量生成整数吗

我希望这是可以理解的:)

使用。它正好包含这种功能。只要你不需要,就不需要产生具体的价值观

?- X #= Y^Z.
Y^Z#=X.

?- X #= Y^Z, [Y,Z]ins 1..3.
 Y^Z#=X,
Y in 1..3,
Z in 1..3.

?- X #= Y^Z, [Y,Z]ins 1..3, labeling([], [Y,Z]).
X = Y, Y = Z, Z = 1 ;
X = Y, Y = 1,
Z = 2 ;
X = Y, Y = 1,
Z = 3 ;
X = Y, Y = 2,
Z = 1 ;
X = 4,
Y = Z, Z = 2 ;
X = 8,
Y = 2,
Z = 3 ;
X = Y, Y = 3,
Z = 1 ;
X = 9,
Y = 3,
Z = 2 ;
X = 27,
Y = Z, Z = 3.

如前所述,您的问题似乎无法解决,那么我想我将以不同的方式处理整个问题,生成最大数量的令牌的所有AST

genAst(Val, Env, Ast) :-
    length(Tokens, N),
    (N > 10, !, fail ; true),
    phrase(sum(Ast), Tokens),
    ev(Ast, Env, Val).

sum(sum(A,B)) --> [+], mul(A), sum(B).
sum(N) --> mul(N).

mul(mul(N,X)) --> [*], xer(X), num(N).
mul(N) --> xer(N).

xer(exp(x,N)) --> [^,x], num(N).
xer(var(x)) --> [x].
xer(N) --> num(N).

%num(num(X)) --> [X], {var(X) -> between(1,9,X) ; integer(X)}.
num(num(X)) --> [X], {X=2;X=3}.
屈服

?- genAst(6,2,A).
A = sum(num(3), num(3)) ;
A = mul(num(3), var(x)) ;
A = mul(num(3), num(2)) ;
A = mul(num(2), num(3)) ;
A = sum(mul(num(2), var(x)), var(x)) ;
A = sum(mul(num(2), var(x)), num(2)) ;
A = sum(mul(num(2), num(2)), var(x)) ;
A = sum(mul(num(2), num(2)), num(2)) ;
A = sum(exp(x, num(2)), var(x)) ;
A = sum(exp(x, num(2)), num(2)) ;
A = sum(var(x), sum(var(x), var(x))) ;
A = sum(var(x), sum(var(x), num(2))) ;
A = sum(var(x), sum(num(2), var(x))) ;
A = sum(var(x), sum(num(2), num(2))) ;
A = sum(var(x), mul(num(2), var(x))) ;
A = sum(var(x), mul(num(2), num(2))) ;
A = sum(var(x), exp(x, num(2))) ;
A = sum(num(2), sum(var(x), var(x))) ;
A = sum(num(2), sum(var(x), num(2))) ;
A = sum(num(2), sum(num(2), var(x))) ;
A = sum(num(2), sum(num(2), num(2))) ;
A = sum(num(2), mul(num(2), var(x))) ;
A = sum(num(2), mul(num(2), num(2))) ;
A = sum(num(2), exp(x, num(2))) ;
false.

需要限制此DCG中输入的长度,因为右递归非终端和//1

Oops对不起,我读的是“绑定”而不是“未绑定”。在这种情况下,您不能使用
is
。左侧必须是单个未绑定变量,右侧必须是所有绑定变量。Prolog不会列举
is/2
表达式的可能解决方案。当然,您可以使用
var/1
nonvar/1
。好的,我有没有办法问Prolog例如4=:=2^X?这也给了我“未实例化的参数”,但我尝试了4==2^X和4=2^X,结果无效
=:=
运算符要求所有内容都实例化。通过查询
4=:=2^X
我想你的意思是想要
log2(4)
。因此,您可以使用
X是log10(4)/log10(2)。
然后使用prolog解释器和其他算术函数来确定它是否为整数。或者,由于基数是
2
,您可以轻松创建一个谓词,使用移位来执行
log2