Domanda

Sto lavorando su un incarico in cui ho creato un parser per un linguaggio aritmetico di notazione prefisso.Ho bisogno di scrivere un predicato che costruisce un AST per qualsiasi dato valore V (cioè generare un AST a tale che ogni volta che viene valutato il suo valore è V).La mia idea è stata abbastanza semplice:

genAst(Val, Env, Ast) :-
   ev(Ast, Env, Val).
.

Dove EV è il predicato di valutazione.Quando eseguo questo ottengo l'errore sul titolo relativo a questa parte del predicato EV:

ev(xer_(power(N)), Env, V) :-
   integer(N),
   V is Env^N. %THIS LINE
.

dove entrambi i V e N sono assunti.Sto lottando per pensare a un altro modo elegante per farlo, qualcuno sa come potrei fare in modo che Prolog generati numeri interi per queste due variabili?

Spero che fosse comprensibile :)

È stato utile?

Soluzione

Come posato, il tuo problema sembra irrisolvibile, quindi penso di affrontare tutto il problema in modo diverso, generando tutto ASTS fino a un numero massimo di token.

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}.
.

rendimenti

?- 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.
.

Limitando la lunghezza dell'ingresso in questo DCG è richiesto a causa della sum RECURSIVE non terminale // 1

Altri suggerimenti

Utilizzare library(clpfd) .Contiene esattamente quel tipo di funzionalità.E non è necessario generare valori concreti, purché non ne hai bisogno!

?- 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.
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top