/ / Reemplazo de múltiples términos de una lista en prólogo - reemplazar, prólogo, expresión

reemplazar múltiples términos de una lista en prólogo - reemplazar, prólogo, expresión

He definido un predicado replace(word_to_be_replaced, replacement, [List_requires_replacement], [storing_List] ) y lo estoy usando para simplificar expresiones aritméticas como: -

simplify([Head|Tail], Simplified) :-
(replace(add(a,a), 2*a, [Head|Tail], L) ; L = [Head|Tail]), !, Simplified = L.

Ahora el problema es que me gustaría reemplazar términos comox+y+x por 2*x+y también. La expresión aritmética que ingresa el usuario será de la siguiente forma ejemplo add(x,div(1,z)) Por favor, ayuda tan pronto como sea posible. Gracias.

Respuestas

2 para la respuesta № 1

Necesitas normalizar tus términos de alguna manera. Esto es un altamente incompleto Bosquejo de cómo me sentiría tentado de acercarme a él. Creo que el enfoque podría ser confirmado, pero tendrá que hacer una doble comprobación de que maneja todos los casos correctamente.

Primero, note como se ve en forma canónica:

?- write_canonical(x+y+x).
+(+(x,y),x)
true.

Ahí está el quid del problema. Uno x está en lo profundo del árbol. El otro está en un nivel diferente. Necesitamos tenerlos a todos en el mismo lugar para que podamos procesarlos juntos. Esto significa que queremos moverlos a la misma lista de alguna manera. Creo que queremos [+, x, y, x] porque entonces podemos clasificar eso en [+, x, x, y] y luego procesarlo de forma recursiva.

?- x+y+x =.. Q.
Q = [+, x+y, x].

Mejor, pero no todo el camino todavía.

expand(Var, Var) :- number(Var) ; atom(Var).
expand(Term, Expanded) :-
(+ number(Var), + atom(Var)),
Term =.. Parts,
maplist(expand, Parts, Expanded).

?- expand(x+y+x, Q).
Q = [+, [+, x, y], x] ;

Mejor. Ahora tenemos que aplanarlo de alguna manera.

flatten_expr([Op, [Op|Inner] | Outer], Result) :-
append([Op|Inner], Outer, Result).
flatten_expr(Other, Other).

?- expand(x+y+x, Q), flatten_expr(Q, QFlat).
Q = [+, [+, x, y], x],
QFlat = [+, x, y, x]

Si clasificamos en el medio podemos seguir con la vida.

flatten_expr([Op, [Op|Inner] | Outer], Result) :-
append([Op|Inner], Outer, ResultU),
msort(ResultU, Result).
flatten_expr(A, A).

Ahora puedes aplicar tus patrones a estos y simplificarlos.

simplify([+, X, X | Rest0], [+, [*, 2, X] | Rest1]) :-
simplify([+, Rest0], [+, Rest1]).

?- expand(x+y+x, Q), flatten_expr(Q, QFlat), simplify(QFlat, Simplified).
Q = [+, [+, x, y], x],
QFlat = [+, x, x, y],
Simplified = [+, [*, 2, x], y]

Entonces solo necesitas una forma de volver a convertir a la representación algebraica. Si expand/2 un poco mejor, tal vez podría correr hacia atrás para hacer eso, pero este no lo es. Dejo esto como un ejercicio para el estudiante.