prolog - sinonimos - interprete ingles español trabajo
Implementando el corte en el traductor meta prólogo intérprete (1)
Permítanme comenzar con una implementación simple que funcione para muchos programas, pero no para todos.
Uso de catch/3
y throw/1
Este método es definitivamente la forma más sencilla de implementar el corte en ISO Prolog. Sin embargo, no es muy eficiente. La idea básica es que el corte simplemente tiene éxito, y solo al retroceder fallará hasta la última invocación de mi_call/1
. Tenga en cuenta que solo las construcciones mi_call/1
podrán capturar esos cortes. Como consecuencia, todos los objetivos definidos por el usuario deben ser envueltos con mi_call/1
. Lo mismo en consecuencia para built-in como setof/3
.
Una implementación ingenua es:
mi_cut.
mi_cut :- throw(cut).
mi_call(Goal) :-
catch(Goal, cut, fail).
En su meta-intérprete, intercambie dos reglas para:
mi_trace(!, _Depth):-!, ( true ; throw(cut) ).
...
mi_trace(Goal, Depth):-
display(''Call: '', Goal, Depth),
Depth1 is Depth + 1,
catch(
( redo_clause(Depth, Goal, Body),
mi_trace(Body, Depth1)
),
cut,
fail),
display(''Exit: '', Goal, Depth).
Esto funciona para casi todos los programas. Excepto aquellos, que throw(cut)
ellos mismos. O quiere atrapar todas las excepciones. Son estos pequeños detalles los que hacen que la implementación general sea mucho más compleja.
En tu rastreador, no has implementado call/1
, catch/3
, throw/1
por el momento, por lo que estos problemas no se mostrarán; simplemente obtienes un error para esos. (Tal vez por confirmar)
Tengo este meta intérprete de seguimiento, alterado de la pregunta anterior. Prólogo desvinculación de la variable enlazada .
No entiendo cómo interpretar el corte. Gracias al usuario @false que me dijo que el recorte está mal implementado, mi pregunta es, ¿cómo debería implementar el corte en este meta-intérprete?
%tracer
mi_trace(Goal):-
mi_trace(Goal, 0).
mi_trace(V, _):-
var(V), !, throw(error(instantiation_error, _)).
mi_trace(true, _Depth):-!, true.
mi_trace(fail, _Depth):-!, fail.
mi_trace(A > B, _Depth):-!, A > B.
mi_trace(A < B, _Depth):-!, A < B.
mi_trace(A =< B, _Depth):-!, A =< B.
mi_trace(A >= B, _Depth):-!, A >= B.
mi_trace(A = B, _Depth):-!, A = B.
mi_trace(A is B, _Depth):-!, A is B.
mi_trace(/+A, _Depth):-!, /+mi_trace(A, _Depth).
mi_trace(!, _Depth):-!, fail. % <- this is wrong
mi_trace((Goal1, Goal2), Depth):-
!,
mi_trace(Goal1, Depth),
mi_trace(Goal2, Depth).
mi_trace(Goal, Depth):-
display(''Call: '', Goal, Depth),
redo_clause(Depth, Goal, Body),
Depth1 is Depth + 1,
mi_trace(Body, Depth1),
display(''Exit: '', Goal, Depth).
mi_trace(Goal, Depth):-
display(''Fail: '', Goal, Depth),
fail.
redo_clause(Depth, Goal, Body) :-
findall(Goal-Body, clause(Goal, Body), [First|Rest]),
( Goal-Body = First
; length(Rest, RL), length(RestC, RL),
member(Goal-Body,RestC),
display(''Redo: '', Goal, Depth),
Rest = RestC
).
display(Message, Goal, Depth):-
tab(Depth), write(Depth), write('': ''), write(Message),
write(Goal), nl.
trace_query(In, Out, Query):-
consult(In),
tell(Out),
call_with_depth_limit(findall(Query, mi_trace(Query), _Solutions), 30, _XMessage),
writeln(_XMessage),
writeln(_Solutions),
told,
unload_file(In),
true.