Промышленный пролог / 2, аргументы не призваны
-
21-12-2019 - |
Вопрос
Я работаю над заданием, где я создал анализатор для арифметического языка префикса.Мне нужно написать предикат, который создает AST для любого данного значения V (I.E. Создание AS A 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 не связаны.Я изо всех сил пытаюсь думать о другом элегантном способе сделать это, кто-нибудь знает, как я мог сделать пролог генерировать целые числа для этих двух переменных?
Я надеюсь, что это было понятно :)
Решение
Как поставлено, ваша проблема кажется неразрешимой, то я думаю, что я бы подойдет всю проблему по-другому, генерирующую ASTS at em> 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
Другие советы
Используйте library(clpfd)
.Он содержит ровно такую функциональность.И нет необходимости генерировать конкретные ценности, пока вы их не нуждаетесь!
?- 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.
.