Laboratorio 4: PROLOG


---------------------------------------

1. Instrucciones basicas:


Para comenzar a trabajar con el Amzi Explorer debemos lanzar un listener(Listener/Start).
Crear un nuevo fichero donde cargaremos las reglas. Una vez creado consultarlo en el listener.
Si lo modificamos podemos reconsultar posteriormente. En el Listener ya podemos hacer consultas.

En los ejemplos se aconseja utilizar el depurador para entender mejor el modo de funcionamiento de PROLOG.
 

2. Hechos (facts)

---------------------------------------------------------

Ejemplo 1:

likes(john,fish).
likes(john,mary).
likes(mary,book).
likes(john,book).

Ejemplo 2:
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).

door(office, hall).
door(kitchen, office).
door(hall, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).

location(desk, office).
location(apple, kitchen).
location(flashlight, desk).
location('washing machine', cellar).
location(nani, 'washing machine').
location(broccoli, kitchen).
location(crackers, kitchen).
location(computer, office).

turned_off(flashlight).
here(kitchen).
 

3. Consultas simples

----------------------------------------------------------
Ejemplo 1:

?-likes(john,money).
?-likes(mary,book).

Ejemplo 2:

?- room(office).
?- room(attic).
?- location(apple, kitchen).
?- location(kitchen, apple).
?- door(office, hall).
?- door(hall,office).
 

4. Variables

----------------------------------------------------------
Ejemplo 1:

likes(john, X).

Ejemplo 2:

?- room(X).
?- location(Thing, Place).
?- location(Thing, kitchen).
 

5. Consultas compuestas

-----------------------------------------------------------
Ejemplo 1:

?- likes(joe,mary),likes(mary,joe).

Ejemplo 2:

?- door(kitchen, R),location(T,R).
 

6. Built-in predicates

-------------------------------------------------------
?- location(X, kitchen), write(X) ,nl, fail.
 
 

7. Operadores

-----------------------------------------------------------

Ejemplo 1:

reina(rhodri, 844,878).
reina(anarawd,878,916).
reina(cadwallon,985,999).
reina(buba, 1000,1020).
reina(bob,1010,1200).
reina(tom,1200,1999).

gobierna(X,Y):-reina(X,A,B),Y >= A,Y =< B.
 

Ejemplo 2:

poblacion(usa,203).
poblacion(india,548).
poblacion(china,800).
poblacion(brasil,108).
area(usa,3).
area(india,1).
area(china,4).
area(brasil,3).

densidad(X,Y) :-
 poblacion(X,P),
 area(X,A),
 Y is P/A.
 
 

8. Reglas

------------------------------------------------------
connect(X,Y) :- door(X,Y).
connect(X,Y) :- door(Y,X).

?- connect(kitchen, office).
?- connect(office, kitchen).
?- connect(X,Y).

list_things(Place) :-
     location(X, Place),
       tab(2),
       write(X),
       nl,
       fail.
 

9. Acceso a datos

--------------------------------------------------------------
move(Place):-
       retract(here(X)),
       asserta(here(Place)).

can_go(Place):-
       here(X),
       connect(X, Place).

goto(Place):-
       can_go(Place),
       move(Place).
 
 

10. Estructuras de datos

-------------------------------------------------------

location_s(object(candle, red, small, 1), kitchen).
location_s(object(apple, red, small, 1), kitchen).
location_s(object(apple, green, small, 1), kitchen).
location_s(object(table, blue, big, 50), kitchen).
 

?- location_s(X, kitchen).
?- location_s(object(X, red, _, _), kitchen).
 
 
 

11. Recursión

----------------------------------------------------------
location(envelope, desk).
location(stamp, envelope).
location(key, envelope).

is_contained_in(T1,T2) :-  location(T1,T2).
is_contained_in(T1,T2) :-
       location(X,T2),
       is_contained_in(T1,X).

?- is_contained_in(X, office).
 

12. Listas

-----------------------------------------------------------

p([1,2,3]).
p([the,cat,sat,[on,the,mat]]).

?- p([X|Y]).
?- p([_,_,_,[_|X] ]).

member(X,[X|_]).
member(X,[_|Y]):-member(X,Y).

longitud([],0).
longitud([H|T],N) :- longitud(T,N1), N is N1 + 1.

listlen(L,N) :- lenacc(L,0,N).
lenacc([],A,A).
lenacc([H|T],A,N) :- A1 is A +1, lenacc(T,A1,N).

append([],X,X).
append([H|T1],X,[H|T2]) :- append(T1,X,T2).
 

change(you,i).
change(are,[am,not]).
change(french,german).
change(do,no).
change(X,X).
alter([],[]).
alter([H|T], [X |Y]) :- change(H,X),alter(T,Y).
 
 

13. Cut

---------------------------------------------------
data(one).
data(two).
data(three).
cut_test_a(X) :-  data(X).
cut_test_a('last clause').

?-cut_test_a(X), write(X), nl, fail.

cut_test_b(X) :- data(X), !.
cut_test_b('last clause').

?- cut_test_b(X), write(X), nl, fail.

cut_test_c(X,Y) :-
       data(X),
       !,
       data(Y).
cut_test_c('last clause').

?- cut_test_c(X,Y), write(X-Y), nl, fail.
 

14. Unificación

-------------------------------------------------------
?- a = a.
?- a = b.
?- location(apple, kitchen) =  location(apple, kitchen).
?- location(apple, kitchen) =   location(pear, kitchen).
?- a(b,c(d,e(f,g))) = a(b,c(d,e(f,g))).
?- a(b,c(d,e(f,g))) = a(b,c(d,e(g,f))).
?- X = a.
?- 4 = Y.
?- location(apple, kitchen) = location(apple, X).
?- location(X,Y) = location(apple, kitchen).
?- location(apple, X) = location(Y, kitchen).
 

15. Iteración

------------------------------------------------------------
command_loop:-
     repeat,
     write('Enter end to exit): '),
     read(X),
     write(X), nl,
     X = end.
 

16. Simulación de Orientacion a Objetos y polimorfismo

-------------------------------------------------------------

member(X, [X, _ ]).
member(X,[Y | _ ]) :- X = Y.
member(X,[_|Y]) :- member(X,Y).
oo_class( rectangle(H, W),
          methods([ ( area(A) :- A is H * W ),
                    ( perimeter(P) :- P is 2 * (H + W) )
                  ]) ).
oo_class( circle(R),
          methods([ ( area(A) :- A is  R * R ),
                    ( perimeter(P) :- 2 * R )
                  ]) ).

oo_send(Obj, Mess) :-
  oo_class(Obj, methods(Ms)),
  member((Mess :- Meth), Ms),
  call(Meth).

shapes([rectangle(2, 3), circle(10), rectangle(4, 5), circle(4)]).
go :-
shapes(L),
  member(S, L),
  oo_send(S, area(A)),
   write('el area de'),tab(2),write(S),write('='),write(A), nl,
  fail.

Para ejecutarlo:
?-go.
 
 

Ejercicios:

 

 

1.- Crear las reglas necesarias para establecer si Y es descendiente de X.
    Tenemos una base de datos de reglas como
 padre(buba,buba1).
 padre(buba,buba2).
 padre(buba,buba3).
 padre(buba1,pepe1).
 padre(buba1,pepe2). 
 padre(pepe2,juan)
     Crear la jerarquia que querais y posteriormente hacer preguntas como:
 ¿juan es descendiente de buba ?
 Dime todos los descendientes de buba.
 Dime todos los ascendientes de juan.

2.- Crear las primitivas necesarias para que dada una lista de enteros apliquemos la funcion incremento
sobre cada elemento de la lista.
Ej:   [1,2,3]  -> [2,3,4]
 ¿ Como conseguiriamos aqui aplicar una "función genérica" sobre la lista? Es decir, aplicar la
 suma, o el producto, o elevar cada número al cubo.

3.- Utilizando las primitivas de manejo de datos (assert y retract) crear las primitivas 
necesarias para coger un objeto y dejar un objeto en una habitación de nuestro juego de aventuras. 

4. Problema de comprensión de los operadores.
 Dados los hechos:
 sum(3).
 sum(5).
 sum(X+Y).
¿ Que responderá el entorno en esta cuestión ?
 ?- sum(2+3).
¿ por que ?

5. Estructuras de datos:Crear el tipo de datos coche, cuyos tipos de datos serán la marca 
y el precio. 
a) Hacer una primitiva que acepte dos coches y nos diga si uno es más caro que otro.
b) Hacer las primitivas necesarias para que dados dos coches nos devuelva el más barato.
  barato(coche(100,bmw),coche(10,seat),Z).
 Z=coche(10,seat).