Anda di halaman 1dari 52

Prolog V 1

V. E/S en Prolog
Jorge Cabrera Gmez
Departamento de Informtica y Sistemas
Universidad de Las Palmas de Gran Canaria
Prolog V 2
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 3

Terminal


Programa

Prolog

Fichero 1
Fichero 2
...
Fichero 4
Fichero 3
...
user
user
input
streams
output
streams
El modelo de E/S
Prolog V 4
Modos de Comunicacin con ficheros


Streams de entrada/salida implcitos
(Estndar)


Streams de entrada/salida explcitos
Prolog V 5
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)
...
see(fichero1),
lee_de_fichero(Datos),
see(user),
...
tell(NombreFichero)
stream de entrada stream de salida
...
tell(fichero1),
escribe_en_fichero(Datos),
tell(user),
...
seen
told
Prolog V 6
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 7
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 8
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 9
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 10
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 11
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 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 27
Siguiente item: 34.
El cubo de 34 is 39304
Siguiente item: stop.

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

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]]).
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] ]).
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 ]).
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 ]).
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
Prolog V 19
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([]).
?- read_line(Line).
|: hola
X = [104, 111, 108, 97].

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

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

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 trmino
procesar_fichero. % Resto del fichero
Esquema bsico para procesar un fichero de trminos
Prolog V 22
browse(File) :-
seeing(Old), /* Lo salvamos para despus */
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
Prolog V 23
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 el siguiente carcter del stream de
entrada. C es el cdigo ASCII del carcter
?- get0(X).
| 1
X = 49
Yes
get(C) Lee el siguiente carcter del stream de
entrada diferente del espacio. C es el cdigo
ASCII del carcter.
?- get(X).
|
| 2
X = 50
Yes
Aqu espacio en blanco + [ENTER]
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 blancos
put(C),
haz_el_resto(C).

haz_el_resto(Letra) :- corrige.
Elimina mltiples espacios entre
palabras de una frase terminada
por un punto
?- corrige.
| Erase una vez un .
Erase una vez un .
Yes
Prolog V 25


Lo que hay que hacer:

1. Leer el texto del fichero
2. 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 nmero de ocurrencias de una palabra en
un texto
Prolog V 26
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 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 < 32
Char2 > 32,
!.
blanks([], []) :- !.
blanks([Char | Chars], RemainingChars) :-
Char =< 32,
blanks(Chars, RemainingChars).
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 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 29
% 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 30
% 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 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)

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 = 112
Yes
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
Prolog V 34
Lectura de programas


consult(+Fichero)

[Fichero1, Fichero2]


reconsult(+Fichero)
No es necesario,
(no existe)
en SWI-Polog.
Prolog V 35
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 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 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 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 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 38
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 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] ;

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
Prolog V 41
/***************************************************************
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([ ],[ ]).
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
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
Prolog V 43
% 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] ),
dif_aux(Xs,Ys1,Zs).
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).

% Alternativa
set_union2(Xs,Ys,USs):-
append(Xs,Ys,ULs),
list_to_set(ULs,USs).
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 interseccin de los conjuntos Xs e Ys.

Prolog V 46
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
Prolog V 47
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).
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).
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
Prolog V 49
% Problema 11.
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
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 if-
then-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.
X = 2 Y = 3 Z = 8 W = 1 Val2 = 4 Val4 = 8

SWI-Prolog
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
Prolog V 51
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.
Problemas
SWI-Prolog
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