Practica Prolog

14
Práctica 3 Tutorial de (Visual Prolog) Parte II

Transcript of Practica Prolog

Page 1: Practica Prolog

Práctica 3

Tutorial de (Visual Prolog)

Parte II

Page 2: Practica Prolog

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

Page 3: Practica Prolog

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 …

Page 4: Practica Prolog

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!

Page 5: Practica Prolog

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.

Page 6: Practica Prolog

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…)

Page 7: Practica Prolog

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

Page 8: Practica Prolog

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.

Page 9: Practica Prolog

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).

Page 10: Practica Prolog

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

Page 11: Practica Prolog

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)

...

Page 12: Practica Prolog

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

Page 13: Practica Prolog

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)

Page 14: Practica Prolog

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