Home     Termíny     Cvičení     Projekty     Rezervace termínu
  1   2   3   4   5   6

6. cvičení


Osnova


Metainterprety

Metainterprety (Prologu) jsou interprety, napsané v Prologu, umožňující interpretovat programy v Prologu.

Mějme následující interprety prologovských programů:

Interpret I1

solveI1(Goal):-call(Goal).

Interpret I2

solveI2(true):-!.
solveI2((A,B)):-!,solveI2(A),solveI2(B).
solveI2(X):-predicate_property(X,built_in),!,call(X).
solveI2(X):-clause(X,B),solveI2(B).

Poznámka:
I2 využívá vestavěné predikáty clause/2, který načítá klauzule z interní programové databáze (konzultované programy), a predicate_property, pomocí kterého umí rozlišit, zda volaný predikát je vestavěný nebo uživatelský.

  1. Interpretujte pomocí těchto interpretů predikáty member/2 a g/1.
    
    % kvuli pouziti predikatu clause/2 v metainterpretu I2
    % musime definovat interpretovane programy jako dynamicke
    
    :- dynamic member/2, g/1, g_list/1.
    
    
    member(H, [H|T]).
    member(H, [_|T]):-member(H,T).
    
    
    g(T):-
      var(T),!,fail.
    g(T):-
      atomic(T),!.
    g(T):-
      T=[_|_],!,
      g_list(T).
    g(T):-
      T=..[_|Args],
      g_list(Args).
    
    g_list([]).
    g_list([H|T]):-
      g(H),
      g_list(T).
    
    
  2. Zdůvodněte přesně, proč nefunguje interpretace predikátu g/1 interpretem I2.

  3. Modifikujte interpret I2 tak, aby místo vestavěné unifikace používal následující unifikaci s testem na výskyt proměnné v unifikovaném termu, tzv. occurs_check (chceme zabránit unifikaci typu X=f(X), s(A,A)=s(B,f(B)) a pod.):
    
    unify(A,B):- (atomic(A);atomic(B)),!,A=B.
    unify(A,B):- var(A),var(B),!,A=B.
    unify(A,B):- var(A),!,no_occur(A,B),A=B.
    unify(A,B):- var(B),!,no_occur(B,A),A=B.
    unify([H1|T1],[H2|T2]):- !,unify(H1,H2),unify(T1,T2).
    unify(A,B):- A=..[H1|T1],B=..[H2|T2],H1==H2,unify(T1,T2).
    
    no_occur(A,B):-atomic(B),!.
    no_occur(A,B):-var(B),!,A\==B.
    no_occur(A,[H|T]):-!,no_occur(A,H),no_occur(A,T).
    no_occur(A,B):-B=..[_|T],no_occur(A,T).
    		
    	


    ^