practica prolog
TRANSCRIPT
Práctica 3
Tutorial de (Visual Prolog)
Parte II
Germán Vidal 2 IDR – Práctica 3 Curso 2007/08
Tipos de datos compuestos (1)
PREDICATES
biblioteca(integer,string,string,string,integer)
CLAUSES
biblioteca(6, “El cuervo”, “Edgar A.”, “Poe”, 1845).
DOMAINS
libro = ficha(string,autor,integer)
autor = autor(string,string)
PREDICATES
biblioteca(integer,ficha)
CLAUSES
biblioteca(6, libro(“El cuervo”, autor(“Edgar A.”, “Poe”), 1845)).
Problema: demasiados parámetros (aparentemente) inconexos…
Usamos functores
libro
autor
Germán Vidal 3 IDR – Práctica 3 Curso 2007/08
Tipos de datos compuestos (2)
Es posible usar “;” cuando hay tipos alternativos:
DOMAINS
dato = integer ; char
Error! Los tipos alternativos requieren un functor diferente
DOMAINS
dato = i(integer) ; c(char)
Ejemplos:
i(38), c(‘a’), i(-23), c(‘A’), …
problema dialog_int …
Germán Vidal 4 IDR – Práctica 3 Curso 2007/08
Programación recursiva Intentad evitar la programación iterativa…
Si no hay más remedio:bucle :- generador de soluciones,
cuerpo del bucle,
test. % o bien ‘fail’
bucle. % sólo si usamos fail
Si se parte de una especificación recursiva
Fácil: Convertir funciones en procedimientos
Desanidar funciones
Usar variables temporales (evitar N = N+1!)
Si se parte de una especificación iterativa
Transformarla primero en una especificación recursiva!
Germán Vidal 5 IDR – Práctica 3 Curso 2007/08
Programación recursiva: Ejemplofact(N,Fact)
P := 1;
I := 1;
WHILE I<= N DO
P := P*I;
I := I+1;
Fact := P
fact(N,Fact)
fact_aux(N,Fact,1,1)
fact_aux(N,Fact,I,P)
IF I <= N
THEN P := P*I;
I := I+1;
fact_aux(N,Fact,I,P)
ELSE Fact := P
fact(N,Fact) :- fact_aux(N,Fact,1,1).
fact_aux(N,Fact,I,P) :- I <= N, !,
NewP = P*I,
NewI = I+1,
fact_aux(N,Fact,I,P).
fact_aux(N,Fact,I,P) :- Fact = P.
fact(1,1).
fact(N,M) :-
NN = N-1,
fact(NN,MM),
M = MM*N.
Germán Vidal 6 IDR – Práctica 3 Curso 2007/08
Tipos de datos recursivos: Listas (1)
Declaración:
DOMAINS
lista_enteros = integer*
matriz_enteros = lista_enteros*
elemento = i(integer) ; c(char)
lista_mixta = elemento*
Predefinidos (en un proyecto Visual Prolog):
ILIST (lista de enteros)
SLIST (lista de strings)Usadlos! (los alias dan errores…)
Germán Vidal 7 IDR – Práctica 3 Curso 2007/08
Tipos de datos recursivos: Listas (2)
Notación:
Enumeración: [1, 2, 3, 4]
[Cabeza|Cola]: [1 | [2, 3, 4]]
[1, 2 | [3, 4]]
[1, 2, 3 | [4]]
[1, 2, 3, 4 | []]
Siempre una
secuencia de
elementos
separados por
comas
Siempre
una lista
Germán Vidal 8 IDR – Práctica 3 Curso 2007/08
Tipos de datos recursivos: Listas (3) Manipulación de listas:
Puesto que es un tipo de datos recursivo, hay que
implementar procedimientos recursivos. Generalmente:
Caso base: [] (lista vacía)
Caso general: [H|R] (lista no vacía)
Ejemplos:
Escritura de listas:
escribir([]).
escribir([H|R]) :- write(H), nl, escribir(R).
Calcular el número de elementos:nelem([],0).
nelem([H|R], N) :- nelem(R,M), N = M+1.
Germán Vidal 9 IDR – Práctica 3 Curso 2007/08
Tipos de datos recursivos: Listas (4) Más ejemplos:
Comprobación de pertenencia:
member(X,[X|_]).
member(X,[_|R]) :- member(X,R).
Concatenar dos listas:append([], L, L).
append([H|R], L, [H|RL]) :- append(R, L, RL).
Germán Vidal 10 IDR – Práctica 3 Curso 2007/08
Tipos de datos recursivos: Listas (5)
Para obtener una lista con todas las soluciones a un
procedimiento: findall(Var, Goal, Lista)
Ejemplo: empleado(N,22,_) devuelve N=juan y N=rosa
findall(N,empleado(N,22,_),L) devuelve L=[juan,rosa]
Características de findall:
Var debe aparecer en Goal
Si no hay ninguna solución falla (no devuelve nunca [])
Puede contener repeticiones
Germán Vidal 11 IDR – Práctica 3 Curso 2007/08
La base de datos interna (1)
Declaración:DATABASE – empleados
empleado(string,integer,string) % y se elimina de
% PREDICATES!
CLAUSES % suele estar vacío...
empleado(“juan”, 22, “e1”).
empleado(“rosa”, 19, “e2”).
...
Consultas: como cualquier otro objetivo…
empleado(X,22,Y) -> X=“juan”, Y=“e1”
empleado(“juan”,23,_) -> no (falla)
...
Germán Vidal 12 IDR – Práctica 3 Curso 2007/08
La base de datos interna (2)
Modificación (en tiempo de ejecución):
Añadir nuevas tuplas: assert, asserta, assertzassert(empleado(“pedro”, 20, “e3”))
Eliminar tuplas: retractretract(empleado(“pedro”, 20, “e3”))
retract(empleado(X,Y,Z))
Eliminar todas las tuplas: retractallretractall(empleado(_, 20, _))
Siempre sin variables!
Elimina el primero, backtracking
para seguir eliminando…
Elimina todas los empleados cuya
edad es 20 sin realizar backtracking
Germán Vidal 13 IDR – Práctica 3 Curso 2007/08
La base de datos interna (3)
Operaciones con la base de datos:
Almacenamiento de datos: save(“fichero”, “nombre_BD”)save(“miBD”,empleados)
Consulta: consult(“fichero”, “nombre_BD”)consult(“miBD”,empleados)
Antes de consultar una BD, hay que “limpiar” la actual:retractall(_, empleados)
Germán Vidal 14 IDR – Práctica 3 Curso 2007/08
Ejercicio
Repetir el mismo ejercicio de la sesión anterior (calcular el
nombre del empleado más joven) empleando:
Un procedimiento recursivo
Los operadores assert/retract, findall, etc