140 likes | 291 Views
Práctica 3. Tutorial de (Visual Prolog) Parte II. Tipos de datos compuestos (1). PREDICATES biblioteca(integer,string,string,string,integer) CLAUSES biblioteca(6, “El cuervo”, “Edgar A.”, “Poe”, 1845). Problema: demasiados parámetros (aparentemente) inconexos…. DOMAINS
E N D
Práctica 3 Tutorial de (Visual Prolog) Parte II
Tipos de datos compuestos (1) PREDICATES biblioteca(integer,string,string,string,integer) CLAUSES biblioteca(6, “El cuervo”, “Edgar A.”, “Poe”, 1845). Problema: demasiados parámetros (aparentemente) inconexos… 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)). Usamos functores autor libro
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 …
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!
Programación recursiva: Ejemplo 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) 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) :- 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.
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…)
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
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.
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).
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=juanyN=rosa findall(N,empleado(N,22,_),L)devuelveL=[juan,rosa] • Características de findall: • Var debe aparecer en Goal • Si no hay ninguna solución falla (no devuelve nunca []) • Puede contener repeticiones
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) ...
La base de datos interna (2) • Modificación (en tiempo de ejecución): • Añadir nuevas tuplas: assert, asserta, assertz assert(empleado(“pedro”, 20, “e3”)) • Eliminar tuplas: retract retract(empleado(“pedro”, 20, “e3”)) retract(empleado(X,Y,Z)) • Eliminar todas las tuplas: retractall retractall(empleado(_, 20, _)) Siempre sin variables! Elimina el primero, backtracking para seguir eliminando… Elimina todas los empleados cuya edad es 20 sin realizar backtracking
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)
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