prolog v1 v. e/s en prolog jorge cabrera gámez departamento de informática y sistemas universidad...

52
Prolog V 1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Upload: benita-ines

Post on 22-Apr-2015

6 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 1

V. E/S en Prolog

Jorge Cabrera GámezDepartamento de Informática y Sistemas

Universidad de Las Palmas de Gran Canaria

Page 2: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 2

Índice.El modelo de E/S

Comunicación con ficherosStreams de entrada/salida implícitosStreams de entrada/salida explícitos

Predicados de E/S orientados a caracteres

Lectura de Programas

Sumario

Page 3: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 3

Terminal

Programa

Prolog

Fichero 1

Fichero 2

...

Fichero 4

Fichero 3

...

useruser

inputstreams

outputstreams

El modelo de E/S

Page 4: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 4

Modos de Comunicación con ficheros

Streams de entrada/salida implícitos(Estándar)

Streams de entrada/salida explícitos

Page 5: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 5

Streams de entrada/salida implícitos

Idea básica: Durante la ejecución de un programa Prolog sólo dos ficheros están activos: uno de entrada y otro de salida

see(NombreFichero)...see(fichero1),lee_de_fichero(Datos),see(user),...

tell(NombreFichero)

stream de entradastream de salida

...tell(fichero1),escribe_en_fichero(Datos),tell(user),...

seen

told

Page 6: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 6

Streams de entrada/salida implícitos

see(+SrcDest) Convierte a SrcDest en el stream de entrada activo. Si SrcDest ya había sido abierto con see/1 y no había sido cerrado, la lectura del fichero se retoma desde la posición actual del puntero. En otro caso, el fichero se abre y el puntero se sitúa al comienzo del mismo.

tell(+SrcDest) Idem. Nótese que en este caso si el fichero no existía se crea y si existía se trunca.

append(+File) Similar a tell/1, pero posiciona el puntero de fichero al final del mismo en vez de truncar un fichero ya existente.

Page 7: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 7

Streams de entrada/salida implícitos

seeing(?SrcDest) Unifica el nombre del stream de entrada activo con SrcDest

telling(?SrcDest) Unifica el nombre del stream de salida activo con SrcDest

Page 8: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 8

Streams de entrada/salida explícitos

open(+SrcDest, +Modo, -Stream, +Opciones)

* Stream: manejador del stream. * Modo: read, write, append o update. * Opciones: una lista de opciones.

type(Type): text (defecto) o binary.alias(Atom): Fija un nombre para el stream.

?- open(foo, read, S, [alias(in)]). buffer(Buffering): Opciones de buffering de la salida. fullf (defecto): buffering completo.

line: buffering por líneasfalse: no se realiza buffering

close(+Stream)

Page 9: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 9

Streams de entrada/salida explícitos

seek(+Stream, +Offset, +Método, -NuevaPosición)

Reposiciona el puntero del stream a la posición dada. Offset: Indica el número de bytes del desplazamiento. Método: bof (desde el principio) current (desde la posición actual) eof (desde el final) NuevaPosición: El nuevo offset desde el comienzo del stream

Page 10: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 10

Streams de entrada/salida explícitos

set_input(+Stream) Convierte Stream en el stream de entrada activo.

open(file, read, Stream), set_input(Stream). es equivalente a:

see(file). set_output(+Stream)

current_input(-Stream)

current_output(-Stream)

Page 11: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 11

Read/Write

read(X)Predicado predefinido que permite leer un términodel stream de entrada.

Si el argumento de read no es unificable con el término a leer, read falla.

read es determinista: si read falla, no se intentaleer otro término en el backtracking.

write(X)Predicado predefinido que permite escribir un términoen el stream de salida.

Page 12: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 12

Read/Write

Ejemplo:

cubo :-write(´Siguiente item: ´),read(X),procesa(X).

procesa(stop) :- !.

procesa(N) :-C is N*N*N, tab(3),write(´El cubo de ´),write(N),write(´ is ´), write(C), nl,cubo.

?- cubo.Siguiente item: 3. El cubo de 3 is 27Siguiente item: 34. El cubo de 34 is 39304Siguiente item: stop.

Yes

Page 13: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 13

Read/Write

Ejemplo:

barras( [ ] ).

barras( [ L| LL] ) :-estrellas(L), nl,barras(LL).

estrellas(N) :-N > 0,write(*),N1 is N-1,estrellas(N1).

estrellas(N) :- N =< 0.

?- barras([1,2,5,3,4]).***************

Yes

?- barras([1,2,5,3,4]).

Page 14: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 14

Read/Write

Ejemplo:

escribe_lista( [ ] ).

escribe_lista( [ L| LL] ) :-una_linea(L), nl,escribe_lista(LL).

una_linea( [ ] ).

una_linea( [ X | L ] ) :-write(X), tab(1),una_linea(L).

?- escribe_lista([[2],[a,d],[q,w]]).

2 a d q w

Yes

?- escribe_lista([a, b]).

No

?- escribe_lista([[2],[a,d],[q,w]]).

Page 15: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 15

Read/Write

Ejemplo:

pp_lista(L) :- pp(L,0).

pp([H|T], I) :- !, J is I+3, pp(H,J), ppx(T,J), nl.

pp(X, I) :- tab(I), write(X), nl.

ppx([ ], _).ppx([H|T], I) :-

pp(H, I), ppx(T, I).

?- pp_lista([[a,s],[1,[2],3]]). a s

1 2

3

Yes

?- pp_lista([ [a,s], [1, [2], 3] ]).

Page 16: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 16

Read/Write

Ejemplo:

pp_palabras([ ]) :- nl.pp_palabras([H|T]) :- write(H),

T == [], !, write(.);tab(1), pp_palabras(T).

?- pp_palabras([mi, mamá, me, ama ]).mi mamá me ama .

Yes

?- pp_palabras([mi, mamá, me, ama ]).

Page 17: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 17

Read/Write

Ejemplo:

pp_palabras([ ]) :- nl.pp_palabras([W|Ws]) :-

write(W), Ws == [] -> write_ln(.);tab(1), pp_palabras(Ws).

?- pp_palabras([mi, mamá, me, ama ]).mi mamá me ama .

Yes

?- pp_palabras([mi, mamá, me, ama ]).

Page 18: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 18

Ejemplo:

pp_palabras([]) :- nl.pp_palabras([H|T]) :-

name(H,[A|B]), es_letra(A,C), name(H1,[C|B]),palabras_aux([H1|T]).

pp_palabras(L) :- palabras_aux(L).

palabras_aux([]) :- nl.palabras_aux([H|T]) :-

write(H), T == [] -> write_ln(.);tab(1), palabras_aux(T).

es_letra(A,A1) :-A =< 122, A >= 97, !, A1 is A-32;A =< 90, A >= 65, A1 is A.

?- pp_palabras([mamá,me, mima]).Mamá me mima .Yes

?- pp_palabras([‘Mamá’,me, mima]).Mamá me mima .Yes

Page 19: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 19

Una utilidad: Cómo leer del teclado una línea sin tener que terminarla en un punto final.

% read_line(-Line)% Reads characters from the keyboard until % it reaches an eof or a new line.read_line([Char | List]) :-

get0(Char),Char =\= -1, % EOFChar =\= 10, % New line!,read_line(List).

read_line([]).

?- read_line(Line).|: holaX = [104, 111, 108, 97].

Page 20: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 20

Otra utilidad: Cómo leer todas las líneas de texto de un fichero, devolviendo el contenido como una lista de caracteres.

% read_file(File,Charlist) % Equivalent to read_file_to_codes(File,CharList,[]) % which is a predefined in SWI-Prologread_file(File, CharList) :-

see(File),read_list(CharList),seen.

% read_list(-List)% Reads characters from the the input % it reaches an eof.read_list([Char | List]) :-

get0(Char),Char =\= -1,!,read_list(List).

read_list([]).

Page 21: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 21

..., see(fichero), procesar_fichero, see(user), ...

procesar_fichero :-read(Term),procesar_termino(Term).

procesar_termino(end_of_file) :- !. % Fin

procesar_termino(Term) :-treat(Term), % Se trata el términoprocesar_fichero. % Resto del fichero

Esquema básico para procesar un fichero de términos

Page 22: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 22

browse(File) :- seeing(Old), /* Lo salvamos para después */ see(File), /* Abrimos este fichero */

repeat, read(Data), /* Leemos del fichero */ process(Data), !, seen, /* Cerramos el fichero */ see(Old). /* Volvemos al primero */

process(end_of_file) :- !. process(Data) :-

write(Data), nl, fail.

?- browse('browse.pl').browse(_G249):-seeing(_G251), see(_G249), repeat, read(_G255), process(_G255), !, seen, see(_G251).

process(end_of_file):-!

process(_G249):-write(_G249), nl, fail

Yes

Page 23: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 23

Predicados de E/S orientados a caracteres.

put(C) Escribe el carácter C en el stream de salida

C es el código ASCII del carácter o el propio carácter.

?- put('B'), put(66), put(b), put(98).BBbbYesget0(C) Lee el siguiente carácter del stream de entrada. C es el código ASCII del carácter?- get0(X).| 1X = 49 Yes

get(C) Lee el siguiente carácter del stream de entrada diferente del espacio. C es el código ASCII del carácter.?- get(X).|| 2X = 50 Yes

Aquí espacio en blanco + [ENTER]

Page 24: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 24

put/get

Ejemplo:

corrige :-get0(C),put(C),haz_el_resto(C).

haz_el_resto(46) :- !. % Codigo ASCII del punto (.)

haz_el_resto(32) :- % Codigo ASCII del blanco!,get(C), % No consideramos otros blancosput(C), haz_el_resto(C).

haz_el_resto(Letra) :- corrige.

Elimina múltiples espacios entre palabras de una frase terminada por un punto

?- corrige.| Erase una vez un . Erase una vez un .Yes

Page 25: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 25

Lo que hay que hacer:

1.Leer el texto del fichero2.Agrupar caracteres en palabras (“Tokenize”)3.Ordenar (sin eliminar duplicados)4.Contar los duplicados

El resultado debe ser una lista de pares del tipo:

[Apariciones, Palabra]

Ejercicio:

Contar el número de ocurrencias de una palabra en un texto

Page 26: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 26

Solución:

:-ensure_loaded('tokenize.pl').

word_counter( MyFile, UnigramList):-

% Leer el texto del ficheroread_file_to_codes(MyFile, CharacterList,[]),

%Agrupar caracteres en palabras (“Tokenize”)tokenizes(CharacterList,TokenList),

%Ordenar (sin eliminar duplicados)msort(TokenList, OrderedTokens),

%Contar los duplicadoscount_duplicates(OrderedTokens, UnigramList).

Page 27: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 27

% tokenize(+Chars, -Tokens)% breaks a list of characters into a list of tokens.% It uses blanks/2 that removes the blank characters from% the head of the list and token/3 that builds one% token from the characters of the head of the list.tokenize([], []) :- !.tokenize(Chars, Tokens) :-

blanks(Chars, RemainingChars),tokenize(RemainingChars, Tokens),!.

tokenize(Chars, [Token | Tokens]) :-token(Chars, Token, RemainingChars),tokenize(RemainingChars, Tokens).

% blanks(+Chars, -RemainingChars)% Removes the blank characters from the head of the list of Chars% RemainingChars contains the rest of the list.blanks([Char1, Char2 | Chars], [Char2 | Chars]) :-

Char1 =< 32, % blank = 32, non-printable chars < 32Char2 > 32,!.

blanks([], []) :- !.blanks([Char | Chars], RemainingChars) :-

Char =< 32,blanks(Chars, RemainingChars).

Page 28: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 28

% token(+Chars, -Token, -RemainingChars)% Builds one token from the characters of the head of the list.% Token is the built token and RemainingChars is the rest of the listtoken(Chars, Token, RemainingChars) :-

alphanumeric_token(Chars, TokenChars, RemainingChars),name(Token, TokenChars),!.

token(Chars, Token, RemainingChars) :-others(Chars, TokenChar, RemainingChars),name(Token, [TokenChar]).

% alphanumeric_token(+Chars, -TokenChars, -RemainingChars)% Returns the characters of the first token on the head% of the list.alphanumeric_token([Char1, Char2 | Chars], [Char1], [Char2 | Chars]) :-

alphanumeric(Char1),\+ alphanumeric(Char2),!.

alphanumeric_token([], [], []) :- !.alphanumeric_token([Char | Chars], [Char | TokenChars], RemainingChars) :-

alphanumeric(Char),!,alphanumeric_token(Chars, TokenChars, RemainingChars).

Page 29: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 29

% alphanumeric(+Char)% Checks whether Char is alphanumeric. There are several cases:

% Lower-case letters without accentalphanumeric(Char) :- 97 =< Char, Char =< 122, !.

% Upper-case letters without accentalphanumeric(Char) :- 65 =< Char, Char =< 90, !.

% Accented characters. The values 215 and 247 correspond to% the multiplication and division: × ÷alphanumeric(Char) :-

192 =< Char, Char =< 255,Char =\= 215, Char =\= 247,!.

% Digitsalphanumeric(Char) :-

48 =< Char, Char =< 57,!.

% The oe, OE, and Y" lettersalphanumeric(Char) :-

(Char =:= 140 ; Char =:= 156 ; Char =:= 159),!.

others([Char | Chars], Char, Chars).

Page 30: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 30

% Cuenta el número de veces que un elemento aparece de forma% consecutiva en una lista

count_duplicates(OrderedList, CountedList) :-count_duplicates(OrderedList, 1, [], CountedListRev),reverse(CountedListRev, CountedList).

count_duplicates([X, X | Ordered], N, Counting, Counted) :-N1 is N + 1,!,count_duplicates([X | Ordered], N1, Counting, Counted).

count_duplicates([X | Ordered], N, Counting,Counted) :-!,count_duplicates(Ordered, 1, [[N, X] | Counting], Counted).

count_duplicates([], _, L, L).

Page 31: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 31

nl nl(+Stream)

put(+Char) put(+Stream, +Char)

tab(+Espacios) tab(+Stream, +Espacios)

flush flush(+Stream)

get0(-Char) get0(+Stream,-Char)

get(-Char) get(+Stream,-Char)

peek_byte(-Char) peek_byte(+Stream,-Char)

skip(+Char) skip(+Stream,+Char)

write(+Term) write(+Stream,+Term)

read(-Term) read(+Stream,-Term)

Page 32: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 32

name(?Atom, ?List)

atom_chars(?Atom, ?String)

atom_char(?Atom, ?ASCII)

atom_length(+Atom,-Length)

string_to_atom(?String, ?Atom)

string_to_list(?String, ?List)

string_length(+String, -Length)

string_concat(?String1, ?String2, ?String3)

?- string_to_atom("Hola que tal", A).A = 'Hola que tal' Yes?- string_to_list("Hola que tal",L).L = [72, 111, 108, 97, 32, 113, 117, 101, 32, 116, 97, 108] Yes

?- atom_chars(pepelu, A).A = [112, 101, 112, 101, 108, 117]Yes?- atom_char(p, C).C = 112Yes

Page 33: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 33

write_nl(+Term)

writef (+Format, +Arguments)

swritef (-String, +Format,+Arguments)

format(+Format, +Arguments)

?- X is 17.2, Y is 238, format('Runtime: ~`.t ~2f~34| Inferences: ~`.t ~D~72|~n', [X,Y]).

Runtime: ................... 17.20 Inferences: .................... 238

Page 34: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 34

Lectura de programas

consult(+Fichero)

[Fichero1, Fichero2]

reconsult(+Fichero)

No es necesario,(no existe)en SWI-Polog.

Page 35: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 35

Sumario.

• E/S implícita y explícita. [user_input],

[user_output]

como flujos de entrada salida por defecto.

• read/write para leer y escribir términos.

• get/put para leer y escribir caracteres.

• SWI-Prolog oferta una gran variedad de

predicados

para producir una salida con formato.

• Para leer programas Prolog usar consult

Page 36: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 36

Problemas

10. Implementar en Prolog los siguientes predicados que operan sobre conjuntos:A) permutacion(Xs, Ys), que devuelva en Ys las permutaciones posibles de la lista Xs (nota: cada permutación se consideraría como una solución).B) combinacion(Xs, N, Ys), que devuelva en Ys las combinaciones posibles de los elementos de Xs cuando éstos se toman de N en N.C) diferencia(Xs, Ys, Zs), que devuelva el Zs el conjunto diferencia de los conjuntos (listas) Xs e Ys. El conjunto diferencia debe contener los elementos que aparecen en sólo uno de los conjuntos.D) union(Xs, Ys, Zs), que devuelve en Zs la union (sin duplicados) de los conjuntos Xs e Ys.E) interseccion(Xs, Ys, Zs), que devuelve en Zs la intersección de los conjuntos Xs e Ys.

Page 37: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 37

%Problema 10, A% extract(X,Ys,Zs) Genera la lista Zs extrayendo de la % lista Ys una ocurrencia de X

extract(X,[X|Xs],Xs).

extract(X,[Y|Ys],[Y|Zs]):- extract(X,Ys,Zs).

% permutation(Xs, Zs) % Devuelve en Zs una permutación de los elementos% de la lista Xs. La idea es generar las permutaciones% de los n elementos extrayendo uno de los elementos% mediante extract/3 y generando las permutaciones de % orden inferior (n-1 elementos) a las que se añade % por la cabeza el elemento seleccionado con extract/3.

permutation(Xs, [Z|Zs]):- extract(Z, Xs, Ys), permutation(Ys,Zs).

permutation([ ], [ ]).

Page 38: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 38

2 ?- extract(X,[a,b,c],Xs).

X = a,Xs = [b, c] ;

X = b,Xs = [a, c] ;

X = c,Xs = [a, b] ;

No

Page 39: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 39

[debug] ?- permutation([a,b],Z). T Call: (7) permutation([a, b], _G394) T Call: (8) extract(_G446, [a, b], _G478) T Exit: (8) extract(a, [a, b], [b]) T Call: (8) permutation([b], _G447) T Call: (9) extract(_G449, [b], _G481) T Exit: (9) extract(b, [b], []) T Call: (9) permutation([], _G450) T Call: (10) extract(_G452, [], _G484) T Fail: (10) extract(_G452, [], _G484) T Redo: (9) permutation([], _G450) T Exit: (9) permutation([], []) T Exit: (8) permutation([b], [b]) T Exit: (7) permutation([a, b], [a, b])

Z = [a, b] ;

Page 40: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 40

T Fail: (9) permutation([], _G450) T Redo: (9) extract(_G449, [b], _G481) T Call: (10) extract(_G449, [], _G453) T Fail: (10) extract(_G449, [], _G453) T Fail: (9) extract(_G449, [b], _G481) T Fail: (8) permutation([b], _G447) T Redo: (8) extract(_G446, [a, b], _G478) T Call: (9) extract(_G446, [b], _G450) T Exit: (9) extract(b, [b], []) T Exit: (8) extract(b, [a, b], [a]) T Call: (8) permutation([a], _G447) T Call: (9) extract(_G452, [a], _G484) T Exit: (9) extract(a, [a], []) T Call: (9) permutation([], _G453) T Call: (10) extract(_G455, [], _G487) T Fail: (10) extract(_G455, [], _G487) T Redo: (9) permutation([], _G453) T Exit: (9) permutation([], []) T Exit: (8) permutation([a], [a]) T Exit: (7) permutation([a, b], [b, a])Z = [b, a] Yes

Page 41: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 41

/*************************************************************** Una solución equivalente basada en la idea de insertar elementos****************************************************************/insert(L, X,[X|L]).insert([H|T],X,[H|L]):- insert(T,X,L).

permutation2([ ],[ ]).permutation2([X|Xs],Zs):-

permutation2(Xs,Ys),insert(Ys,X,Zs).

4 ?- insert([1,2],a,L).

L = [a, 1, 2] ;

L = [1, a, 2] ;

L = [1, 2, a] ;

No

Page 42: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 42

%Problema 10, B/***************************************************B) combination(Xs, N, Ys), que devuelva en Ys las combinaciones posibles de los elementos de Xs cuando éstos se toman de N en N.****************************************************/

combination(_,0,[ ]).

combination(Xs,1,[X]):- extract(X,Xs,_).

combination([X|Xs],N,[X|Zs]):-N > 1,N1 is N-1,combination(Xs,N1,Zs).

combination([_|Xs],N,Zs):-N > 1,combination(Xs,N,Zs).

7 ?- combination([1,2,3],2,Cs).

Cs = [1, 2] ;

Cs = [1, 3] ;

Cs = [2, 3] ;

No

Page 43: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 43

% Problema 10, CC) difference(Xs, Ys, Zs), que devuelva el Zs el conjunto diferencia de los conjuntos (listas) Xs e Ys. El conjunto diferencia debe contener los elementos que aparecen en sólo uno de los conjuntos.

difference(Xs,Ys,Zs):-list_to_set(Xs,Xs1), % Eliminar duplicadoslist_to_set(Ys,Ys1), % Eliminar duplicadosdif_aux(Xs1,Ys1,Zs).

dif_aux([ ],Zs,Zs).dif_aux([X|Xs],Ys,Zs):-

(memberchk(X,Ys), !, extract(X,Ys,Ys1);Ys1 = [X|Ys] ),dif_aux(Xs,Ys1,Zs).

Page 44: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 44

%Problema 10, D

set_union(Xs, Ys, Zs), que devuelve en Zs la union (sin duplicados) de los conjuntos Xs e Ys.

set_union([ ], Ys, Zs):- list_to_set(Ys,Zs).set_union([X|Xs],Ys,Zs):-

\+member(X,Ys),!, set_union(Xs,[X|Ys],Zs);set_union(Xs,Ys,Zs).

% Alternativaset_union2(Xs,Ys,USs):-

append(Xs,Ys,ULs),list_to_set(ULs,USs).

Page 45: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 45

set_intersection(Xs,Ys,Zs):- list_to_set(Xs,Xs1),inter_aux(Xs1,Ys,[ ],Zs).

inter_aux([ ], _, Zs, Zs).

inter_aux([X|Xs],Ys,Ws,Zs):-member(X,Ys),!, inter_aux(Xs,Ys,[X|Ws],Zs);inter_aux(Xs,Ys,Ws,Zs).

% Problema 10, E

E) set_intersection(Xs, Ys, Zs), que devuelve en Zs la intersección de los conjuntos Xs e Ys.

Page 46: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 46

11. Implementar el predicado max_lista(Xs, Y) que permita recuperar en Y el máximo de los números contenidos en la lista Xs.

% Problema 11. max_lista([X],X) :- !. % Este cut evita una

% llamada inutil con [ ] max_lista([X|S],M) :-

max_lista(S,P), X < P, !, M is P;M is X.

SWI-Prolog

Page 47: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 47

12. Dada una lista conteniendo números enteros, devolver dos listas conteniendo respectivamente los números positivos (incluido el cero) y los números negativos. Realizar dos implementaciones de este predicado: una sin emplear el predicado cut (!) y otra que sí lo utilice.

% Problema 12.separa([ ], [ ], [ ]).separa([X|S], [X|P], N) :- X >= 0, separa(S, P, N).separa([X|S], P, [X|N]) :- X < 0, separa(S, P, N).

Problemas

SWI-Prolog

separa_cut([ ], [ ], [ ]).separa_cut([X|S], [X|P], N) :- X >= 0, !, separa_cut(S, P, N).separa_cut([X|S], P, [X|N]) :- separa_cut(S, P, N).

Page 48: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 48

?- separa([1,2,-3,4,0,-2],P,N).T Call: ( 7) separa([1, 2, -3, 4, 0, -2], _G250, _G251)T Call: ( 8) separa([2, -3, 4, 0, -2], _G386, _G251)T Call: ( 9) separa([-3, 4, 0, -2], _G389, _G251)T Redo: ( 9) separa([-3, 4, 0, -2], _G389, _G251)T Call: ( 10) separa([4, 0, -2], _G389, _G392)T Call: ( 11) separa([0, -2], _G395, _G392)T Call: ( 12) separa([-2], _G398, _G392)T Redo: ( 12) separa([-2], _G398, _G392)T Call: ( 13) separa([], _G398, _G401)T Exit: ( 13) separa([], [], [])T Exit: ( 12) separa([-2], [], [-2])T Exit: ( 11) separa([0, -2], [0], [-2])T Exit: ( 10) separa([4, 0, -2], [4, 0], [-2])T Exit: ( 9) separa([-3, 4, 0, -2], [4, 0], [-3, -2])T Exit: ( 8) separa([2, -3, 4, 0, -2], [2, 4, 0], [-3, -2])T Exit: ( 7) separa([1, 2, -3, 4, 0, -2], [1, 2, 4, 0], [-3, -2])P = [1, 2, 4, 0]N = [-3, -2] ;

T Redo: ( 11) separa([0, -2], _G395, _G392)T Fail: ( 11) separa([0, -2], _G395, _G392)T Redo: ( 10) separa([4, 0, -2], _G389, _G392)T Fail: ( 10) separa([4, 0, -2], _G389, _G392)T Fail: ( 9) separa([-3, 4, 0, -2], _G389, _G251)T Redo: ( 8) separa([2, -3, 4, 0, -2], _G386, _G251)T Fail: ( 8) separa([2, -3, 4, 0, -2], _G386, _G251)T Redo: ( 7) separa([1, 2, -3, 4, 0, -2], _G250, _G251)T Fail: ( 7) separa([1, 2, -3, 4, 0, -2], _G250, _G251)

No

?- separa_cut([1,2,-3,4,0,-2],P,N).T Call: ( 8) separa_cut([1, 2, -3, 4, 0, -2], _G274, _G275)T Call: ( 9) separa_cut([2, -3, 4, 0, -2], _G410, _G275)T Call: ( 10) separa_cut([-3, 4, 0, -2], _G413, _G275)T Redo: ( 10) separa_cut([-3, 4, 0, -2], _G413, _G275)T Call: ( 11) separa_cut([4, 0, -2], _G413, _G416)T Call: ( 12) separa_cut([0, -2], _G419, _G416)T Call: ( 13) separa_cut([-2], _G422, _G416)T Redo: ( 13) separa_cut([-2], _G422, _G416)T Call: ( 14) separa_cut([], _G422, _G425)T Exit: ( 14) separa_cut([], [], [])T Exit: ( 13) separa_cut([-2], [], [-2])T Exit: ( 12) separa_cut([0, -2], [0], [-2])T Exit: ( 11) separa_cut([4, 0, -2], [4, 0], [-2])T Exit: ( 10) separa_cut([-3, 4, 0, -2], [4, 0], [-3, -2])T Exit: ( 9) separa_cut([2, -3, 4, 0, -2], [2, 4, 0], [-3, -2])T Exit: ( 8) separa_cut([1, 2, -3, 4, 0, -2], [1, 2, 4, 0], [-3, -2])P = [1, 2, 4, 0]N = [-3, -2] ;No

Page 49: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 49

Problemas13. Definir los operadores ‘if’, ‘then’, ‘else’ y ‘:=’ de manera que el siguiente término sea sintácticamente correcto:

if X >Y then Z:= X else Z:= Y

Elegir las precedencias de forma que ‘if’ sea el functor principal. Defina la relación ‘if’ como un pequeño intérprete para una expresión del tipo ‘if-then-else’ de la forma:

if Val1 > Val2 then Var:= Val3 else Var:= Val4

donde Val1, Val2, Val3 y Val4 son números, o variables instanciadas en

números, y Var es una variable. Lo que sigue es un ejemplo de cómo

debería utilizarse este intérprete:

?- X = 2, Y = 3, Val2 is 2*X, Val4 is 4*X,

if Y > Val2 then Z:= Y else Z:= Val4,

if Z > 5 then W:= 1 else W:= 0.

X = 2 Y = 3 Z = 8 W = 1 Val2 = 4 Val4 = 8 SWI-Prolog

Page 50: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 50

% Problema 13.:- op(900, fx, if).:- op(800, xfx, then).:- op(700, xfx, else).:- op(600, xfx, :=).

if Val1 > Val2 then Var:= Val3 else Var:= Val4 :-Val1 > Val2, !, Var = Val3;Var = Val4.

SWI-Prolog

Page 51: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 51

14. Definir el predicado freq(Xs, Ys) de manera que ante una lista de números enteros (Xs) obtenga una lista (Ys) que contenga las frecuencias de aparición de los diferentes elementos de la lista Xs. Por ejemplo:

?- freq([3,3,2,2,1,1,2,2,3,3], A).

A = [2*1,4*2,4*3]

donde la nomenclatura empleada en la lista A indica que existen 2 ocurrencias de 1, 4 de 2 y 4 de 3. Nota: El que la lista resultado salga ordenada puede facilitar la obtención de la solución.

Problemas

SWI-Prolog

Page 52: Prolog V1 V. E/S en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria

Prolog V 52

% Problema 14.freq(L, S) :- freq(L, [], S).freq([], S, S).freq([N|L], S1, S3) :- actualiza(N, S1, S2), freq(L, S2, S3).

% actualiza(clave, listaentrada, listasalida)actualiza(N, [], [1*N]).actualiza(N, [F*N|S], [F1*N|S]) :- !, F1 is F+1.actualiza(N, [F*M|S], [1*N,F*M|S]) :- N < M, !.actualiza(N, [F*M|S], [F*M|S1]) :- N \== M, actualiza(N,S,S1).

?- freq([3,3,2,2,1,1,2,2,3,3], A).

A = [2*1,4*2,4*3]

SWI-Prolog