Anda di halaman 1dari 52

V.

E/S en Prolog

Departamento de Informtica y Sistemas Universidad de Las Palmas de Gran Canaria


Prolog V 1

Jorge Cabrera Gmez

ndice.
El modelo de E/S
Comunicacin con ficheros Streams de entrada/salida implcitos Streams de entrada/salida explcitos Predicados de E/S orientados a caracteres

Lectura de Programas
Sumario
Prolog V 2

El modelo de E/S
Terminal
user user

input Fichero 2 streams

Fichero 1

Programa Prolog

Fichero 4 Fichero 3

...

...

output streams

Prolog V

Modos de Comunicacin con ficheros


Streams de entrada/salida implcitos (Estndar) Streams de entrada/salida explcitos

Prolog V

Streams de entrada/salida implcitos


Idea bsica: Durante la ejecucin de un programa Prolog slo dos ficheros estn activos: uno de entrada y otro de salida see(NombreFichero) seen tell(NombreFichero) told
Prolog V

stream de salida entrada

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

Streams de entrada/salida implcitos


see(+SrcDest) Convierte a SrcDest en el stream de entrada activo. Si SrcDest ya haba sido abierto con see/1 y no haba sido cerrado, la lectura del fichero se retoma desde la posicin actual del puntero. En otro caso, el fichero se abre y el puntero se sita al comienzo del mismo. tell(+SrcDest) Idem. Ntese que en este caso si el fichero no exista se crea y si exista 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.
Prolog V 6

Streams de entrada/salida implcitos


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

Prolog V

Streams de entrada/salida explcitos


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 lneas false: no se realiza buffering close(+Stream)
Prolog V 8

Streams de entrada/salida explcitos


seek(+Stream, +Offset, +Mtodo, -NuevaPosicin) Reposiciona el puntero del stream a la posicin dada. Offset: Indica el nmero de bytes del desplazamiento. Mtodo: bof (desde el principio) current (desde la posicin actual) eof (desde el final) NuevaPosicin: El nuevo offset desde el comienzo del stream

Prolog V

Streams de entrada/salida explcitos


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)

Prolog V

10

Read/Write
read(X) Predicado predefinido que permite leer un trmino del stream de entrada. Si el argumento de read no es unificable con el trmino a leer, read falla. read es determinista: si read falla, no se intenta leer otro trmino en el backtracking.

write(X) Predicado predefinido que permite escribir un trmino en el stream de salida.


Prolog V 11

Read/Write
Ejemplo: cubo :write(Siguiente item: ), read(X), procesa(X). ?- cubo. Siguiente item: 3. El cubo de 3 is 27 Siguiente item: 34. El cubo de 34 is 39304 Siguiente item: stop. Yes

procesa(stop) :- !.
procesa(N) :C is N*N*N, tab(3), write(El cubo de ),write(N), write( is ), write(C), nl, cubo. Prolog V

12

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. Prolog V ?- barras([1,2,5,3,4]). * ** ***** *** **** Yes
13

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

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

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

?- escribe_lista([[2],[a,d],[q,w]]). 2 ad qw Yes ?- escribe_lista([a, b]). No


14

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). Prolog V ?- pp_lista([ [a,s], [1, [2], 3] ]).

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

Yes

15

Read/Write
?- pp_palabras([mi, mam, me, ama ]).

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 Prolog V
16

Read/Write
Ejemplo: ?- pp_palabras([mi, mam, me, ama ]).

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 Prolog V
17

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

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

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 ; Prolog V A =< 90, A >= 65, A1 is A.

18

Una utilidad: Cmo leer del teclado una lnea 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, % EOF Char =\= 10, % New line !, read_line(List). ?- read_line(Line). |: hola read_line([]). X = [104, 111, 108, 97].
Prolog V 19

Otra utilidad: Cmo leer todas las lneas 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-Prolog read_file(File, CharList) :see(File), read_list(CharList), seen.

Prolog V

% 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([]).

20

Esquema bsico para procesar un fichero de trminos


..., 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 trmino procesar_fichero. % Resto del fichero


Prolog V 21

browse(File) :seeing(Old), see(File), repeat, read(Data), process(Data), !, seen, see(Old).

?- browse('browse.pl'). browse(_G249):-seeing(_G251), /* Lo salvamos para despus */ see(_G249), repeat, read(_G255), /* Abrimos este fichero */ process(_G255), !, seen, see(_G251). process(end_of_file):-! /* Leemos del fichero */ process(_G249):-write(_G249), nl, fail /* Cerramos el fichero */ Yes /* Volvemos al primero */

process(end_of_file) :- !. process(Data) :write(Data), nl, fail.


Prolog V 22

Predicados de E/S orientados a caracteres.


put(C) Escribe el carcter C en el stream de salida C es el cdigo ASCII del carcter o el propio carcter.

?- put('B'), put(66), put(b), put(98). BBbb Yes get0(C) Lee get(C) Lee el el siguiente siguiente carcter carcter del del stream stream de de entrada entrada. diferente C es el cdigo del espacio. ASCII C del escarcter el cdigo ASCII del carcter. ?- get0(X). | get(X). ?1 |X = 49 Aqu espacio en blanco + [ENTER] |Yes 2 X = 50 Prolog V 23 Yes

put/get
Ejemplo: corrige :get0(C), put(C), haz_el_resto(C).

?corrige.mltiples espacios entre Elimina | palabras Erase una frase vez un . de una terminada Erase una vez un . por un punto Yes

haz_el_resto(46) :- !.
haz_el_resto(32) :!, get(C), put(C), haz_el_resto(C).
Prolog V

% Codigo ASCII del punto (.)


% Codigo ASCII del blanco

% No consideramos otros blancos

24

haz_el_resto(Letra) :- corrige.

Ejercicio: Contar el nmero de ocurrencias de una palabra en un texto


Lo que hay que hacer: 1. 2. 3. 4. Leer el texto del fichero Agrupar caracteres en palabras (Tokenize) Ordenar (sin eliminar duplicados) Contar los duplicados

El resultado debe ser una lista de pares del tipo:

[Apariciones, Palabra]
Prolog V 25

Solucin:
:-ensure_loaded('tokenize.pl'). word_counter( MyFile, UnigramList):-

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


%Agrupar caracteres en palabras (Tokenize) tokenizes(CharacterList,TokenList), %Ordenar (sin eliminar duplicados) msort(TokenList, OrderedTokens), %Contar los duplicados count_duplicates(OrderedTokens, UnigramList).
Prolog V 26

% 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 < 32 Char2 > 32, !. blanks([], []) :- !. blanks([Char | Chars], RemainingChars) :Char =< 32, blanks(Chars, RemainingChars).
Prolog V

27

% 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 list token(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).
Prolog V

28

% alphanumeric(+Char) % Checks whether Char is alphanumeric. There are several cases: % Lower-case letters without accent alphanumeric(Char) :- 97 =< Char, Char =< 122, !. % Upper-case letters without accent alphanumeric(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, !. % Digits alphanumeric(Char) :48 =< Char, Char =< 57, !. % The oe, OE, and Y" letters alphanumeric(Char) :(Char =:= 140 ; Char =:= 156 ; Char =:= 159), !. others([Char | Chars], Char, Chars).
Prolog V 29

% Cuenta el nmero 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).
Prolog V 30

nl put(+Char)

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

tab(+Espacios)
flush get0(-Char) get(-Char) peek_byte(-Char)

tab(+Stream, +Espacios)
flush(+Stream) get0(+Stream,-Char) get(+Stream,-Char) peek_byte(+Stream,-Char)

skip(+Char)
write(+Term)
Prolog V

skip(+Stream,+Char)
write(+Stream,+Term) read(+Stream,-Term)
31

read(-Term)

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) ?- atom_chars(pepelu, string_to_atom("Hola A). que tal", A). A = [112, 'Hola 101, que tal' 112, 101, 108, 117] string_concat(?String1, ?String2, ?String3) Yes ?- atom_char(p, string_to_list("Hola C). que tal",L). L = [72, C 112 111, 108, 97, 32, 113, 117, 101, 32, 116, 97, 108] Yes V Prolog

32

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

Prolog V

33

Lectura de programas
consult(+Fichero) [Fichero1, Fichero2]

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

Prolog V

34

Sumario.
E/S implcita y explcita. [user_input], [user_output] como flujos de entrada salida por defecto. read/write para leer y escribir trminos. 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

Prolog V

35

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 permutacin se considerara como una solucin). 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 slo 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 interseccin de los conjuntos Xs e Ys.
Prolog V 36

%Problema 10, A % extract(X,Ys,Zs) % extract(X,[X|Xs],Xs).

Genera la lista Zs extrayendo de la lista Ys una ocurrencia de X

extract(X,[Y|Ys],[Y|Zs]):- extract(X,Ys,Zs). % permutation(Xs, Zs) % Devuelve en Zs una permutacin 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 aade % por la cabeza el elemento seleccionado con extract/3. permutation(Xs, [Z|Zs]):- extract(Z, Xs, Ys), permutation(Ys,Zs). permutation([ ], [ ]).
Prolog V 37

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

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

Prolog V

38

[debug] T Call: T Call: T Exit: T Call: T Call: T Exit: T Call: T Call: T Fail: T Redo: T Exit: T Exit: T Exit:

?- permutation([a,b],Z). (7) permutation([a, b], _G394) (8) extract(_G446, [a, b], _G478) (8) extract(a, [a, b], [b]) (8) permutation([b], _G447) (9) extract(_G449, [b], _G481) (9) extract(b, [b], []) (9) permutation([], _G450) (10) extract(_G452, [], _G484) (10) extract(_G452, [], _G484) (9) permutation([], _G450) (9) permutation([], []) (8) permutation([b], [b]) (7) permutation([a, b], [a, b])

Z = [a, b] ;

Prolog V

39

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]) V ZProlog = [b, a] Yes

40

/*************************************************************** Una solucin equivalente basada en la idea de insertar elementos ****************************************************************/ insert(L, X,[X|L]). insert([H|T],X,[H|L]):- insert(T,X,L). permutation2([ ],[ ]). 4 ?- insert([1,2],a,L). permutation2([X|Xs],Zs):permutation2(Xs,Ys), L = [a, 1, 2] ; insert(Ys,X,Zs).

L = [1, a, 2] ;
L = [1, 2, a] ;
Prolog V

No

41

%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, Prolog V combination(Xs,N,Zs).
7 ?- combination([1,2,3],2,Cs). Cs = [1, 2] ; Cs = [1, 3] ; Cs = [2, 3] ; No

42

% Problema 10, C C) 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 slo uno de los conjuntos. difference(Xs,Ys,Zs):list_to_set(Xs,Xs1), % Eliminar duplicados list_to_set(Ys,Ys1), % Eliminar duplicados dif_aux(Xs1,Ys1,Zs). dif_aux([ ],Zs,Zs). dif_aux([X|Xs],Ys,Zs):(memberchk(X,Ys), !, extract(X,Ys,Ys1) ; Ys1 = [X|Ys] ), Prolog V dif_aux(Xs,Ys1,Zs).

43

%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). % Alternativa set_union2(Xs,Ys,USs):append(Xs,Ys,ULs), list_to_set(ULs,USs).
Prolog V 44

% Problema 10, E
E) set_intersection(Xs, Ys, Zs), que devuelve en Zs la interseccin de los conjuntos Xs e Ys.

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).
Prolog V 45

11. Implementar el predicado max_lista(Xs, Y) que permita recuperar en Y el mximo de los nmeros 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
46

Prolog V

Problemas
12. Dada una lista conteniendo nmeros enteros, devolver dos listas conteniendo respectivamente los nmeros positivos (incluido el cero) y los nmeros 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). 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).
Prolog V 47 SWI-Prolog

?- separa([1,2,-3,4,0,-2],P,N). ?- separa_cut([1,2,-3,4,0,-2],P,N). T Call: ( 7) separa([1, 2, -3, 4, 0, -2], _G250, _G251) T Call: ( 8) separa_cut([1, 2, -3, 4, 0, -2], _G274, _G275) T Redo: Call: ( (8) 11) separa([2, separa([0, -3, -2], 4, 0, _G395, -2], _G386, _G392) _G251) T Call: ( 9) separa_cut([2, -3, 4, 0, -2], _G410, _G275) T Fail: Call: ( ( 11) 9) separa([-3, separa([0, -2], 4, 0, _G395, -2], _G389, _G392) _G251) T Call: ( 10) separa_cut([-3, 4, 0, -2], _G413, _G275) T Redo: ( 10) 9) separa([-3, separa([4, 0, 4, -2], 0, -2], _G389, _G389, _G392) _G251) T Redo: ( 10) separa_cut([-3, 4, 0, -2], _G413, _G275) T Fail: Call: ( ( 10) 10) separa([4, separa([4, 0, 0, -2], -2], _G389, _G389, _G392) _G392) T Call: ( 11) separa_cut([4, 0, -2], _G413, _G416) T Fail: Call: ( ( 11) 9) separa([-3, separa([0, -2], 4, 0, _G395, -2], _G389, _G392) _G251) T Call: ( 12) separa_cut([0, -2], _G419, _G416) T Redo: Call: ( 12) ( 8)separa([-2], separa([2, -3, _G398, 4, 0, -2], _G392) _G386, _G251) T Call: ( 13) separa_cut([-2], _G422, _G416) T Fail: Redo: ( ( 8) 12) separa([2, separa([-2], -3, 4, _G398, 0, -2], _G392) _G386, _G251) T Redo: ( 13) separa_cut([-2], _G422, _G416) T Redo: Call: ( 13) ( 7)separa([], separa([1, _G398, 2, -3, 4, _G401) 0, -2], _G250, _G251) T Call: ( 14) separa_cut([], _G422, _G425) T Fail: Exit: ( 13) 7) separa([1, separa([], 2, [], -3, []) 4, 0, -2], _G250, _G251) T Exit: ( 14) separa_cut([], [], []) T Exit: ( 12) separa([-2], [], [-2]) T Exit: ( 13) separa_cut([-2], [], [-2]) T Exit: ( 11) separa([0, -2], [0], [-2]) No T Exit: ( 12) separa_cut([0, -2], [0], [-2]) T Exit: ( 10) separa([4, 0, -2], [4, 0], [-2]) T Exit: ( 11) separa_cut([4, 0, -2], [4, 0], [-2]) T Exit: ( 9) separa([-3, 4, 0, -2], [4, 0], [-3, -2]) T Exit: ( 10) separa_cut([-3, 4, 0, -2], [4, 0], [-3, -2]) T Exit: ( 8) separa([2, -3, 4, 0, -2], [2, 4, 0], [-3, -2]) T Exit: ( 9) separa_cut([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]) T Exit: ( 8) separa_cut([1, 2, -3, 4, 0, -2], [1, 2, 4, 0], [-3, -2]) P = [1, 2, 4, 0] P = [1, 2, 4, 0] N = [-3, -2] ; N = [-3, -2] ; Prolog V No

48

Problemas
13. Definir los operadores if, then, else y := de manera que el siguiente trmino sea sintcticamente correcto: if X >Y then Z:= X else Z:= Y

Elegir las precedencias de forma que if sea el functor principal. Defina la relacin if como un pequeo intrprete para una expresin del tipo ifthen-else de la forma: if Val1 > Val2 then Var:= Val3 else Var:= Val4
donde Val1, Val2, Val3 y Val4 son nmeros, o variables instanciadas en nmeros, y Var es una variable. Lo que sigue es un ejemplo de cmo debera utilizarse este intrprete: ?- 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.
Prolog V X= 2 Y=3

Z=8

W = 1 Val2 = 4

Val4 = 8

49 SWI-Prolog

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

Prolog V

SWI-Prolog

50

Problemas
14. Definir el predicado freq(Xs, Ys) de manera que ante una lista de nmeros enteros (Xs) obtenga una lista (Ys) que contenga las frecuencias de aparicin 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 obtencin de la solucin.

Prolog V

51 SWI-Prolog

% 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]
52 SWI-Prolog

Prolog V

Anda mungkin juga menyukai