|
|
INTELIGENCIA
ARTIFICIAL 1-USAC
|
Programas
de ejemplo en Prolog
01 Mínimo común múltiplo
02 Máximo
común divisor
03 Factorial
04 Potenciación
05 Sumatorias
06 Producto
07 Programa
de parentesco sin menú
08 Programa
de parentesco con menú
09 Arboles
binarios
10 Operaciones
con listas
11 Sucesión
de números naturales
12 Problema
de las 8 reinas
MCM
El siguiente programa
calcula el mínimo común multiplo de dos números, para
ello los datos se deben ingresar de la siguiente manera:
mcm(A, B, A1, B1, C). A y B son los dos números a
ingresar, A1 y B1 toman el mismo valor de A, B y C se
ingresa sin ningún valor. Quedaria así: mcd(12, 20, 12,
20, C) obteniendo como resultado 60.
domains
A,B,C,A1,B1=integer
predicates
mcm(A,B,A1,B1,C)
clauses
mcm(A,B,A1,B1,C):-A=B,C=A*(A1/A)*(B1/A).
mcm(A,B,A1,B1,C):-A>B,X=A-B,mcm(X,B,A1,B1,C).
mcm(A,B,A1,B1,C):-A
Regresar
al indice
MCD
El siguiente programa
calcula el máximo común divisor de dos números, para
ello los datos se deben ingresar de la siguiente manera:
mcd(A, B, C). A y B son los dos números a ingresar y C
se ingresa sin ningún valor. Quedaria así: mcd(48, 60,
C) obteniendo como resultado 12.
domains
A, B, C = integer
predicates
mcd(A, B, C)
clauses
mcd(A,B,C):-A = B,C = A.
mcd(A,B,C):-A > B, X = A - B, mcd(X, B, C).
mcd(A,B,C):-A < B, Y = B - A, mcd(A, Y, C).
Regresar
al indice
FACTORIAL
El
siguiente programa calcula el factorial de un número N.
El ejemplo es: FACTO(1,1,N) se deben poner siempre los 2
primeros unos y calcula el factorial.
DOMAINS
NUM = INTEGER
PREDICATES
FACTO(NUM,NUM,NUM)
CLAUSES
FACTO(A,B,C):-X=B+1,Z=A*X,X<=C,
WRITE(Z),NL,FACTO(Z,X,C).
Regresar
al indice
POTENCIACIÓN
El siguiente programa
calcula la potencia de un numero, para ello se deben
ingresar los datos de la siguiente forma: exponente(A, B,
C, D). A es el número base y B es el exponente, en C
coloca un 1 y D toma el mismo valor de A. Quedaria asi:
exponente(3,2,1,3) para obtener como resultado 9.
domains
var = real
predicates
exponente(var, var, var, var)
clauses
exponente(A, B, C, D):- Y = C+1, N = A * D, C < B,
write("EXP = ", D, "*", A,
"=", N), nl, exponente(A, B, Y, N)
Regresar
al indice
SUMATORIAS
El siguiente programa
calcula la sumatoria de los N primeros numeros enteros
positivos, para ello los datos se deben ingresar de la
siguiente forma: suma(A,B,C). A toma el valor de 1, B
toma el valor de 1 y en C toma el valor de los N numeros
a sumar. Quedaria así: suma(1,1,3) obteniendo la
sumatoria desde 1 hasta 3 igual 6.
domains
var = real
predicates
suma(var, var, var)
clauses
suma(A,B,C):- X = B + 1, Z= A + X, X <= C, write("SUM
=",A ,"+", X, "=",Z), nl, suma(Z,
X, C).
Regresar
al indice
PRODUCTO
El siguiente programa
calcula el producto de dos números utilizando sumas
sucesivas, para ello los datos se deben ingresar de la
siguiente forma: mult(A, B, C, D). A y B son los numero a
multiplicar, en C coloca un 1 y D toma el mismo valor de
A. Quedaria así: mult(3, 5, 1, 3) obteniendo como
resultado 15.
domains
var = real
predicates
mult(var, var, var, var)
clauses
mult(A,B,C,D):- Z = C + 1, L=A + D, C < B, write("MULTIPLICACION
= ",D," + ",A," = ", L), nl,
mult(A,B,Z,L).
Regresar
al indice
PARENTESCO 1
El siguiente programa esta
hecho en lenguaje de programacion lógica Prolog y su
función es la de calcular cualquier parentesco en el árbol
genaológico de una familia, como por ejemplo los hijos
son de tal padre, el abuelo tiene los siguientes nietos,
los hermanos son y así sucesivamente.
domains
perso=symbol
predicates
hombre(perso)
mujer(perso)
pariente(perso,perso)
padre(perso,perso)
madre(perso,perso)
hijo(perso,perso)
hija(perso,perso)
hermano_de(perso,perso)
hermana_de(perso,perso)
abuelo(perso,perso)
abuela(perso,perso)
tio_de(perso,perso)
ancestro(perso,perso,perso)
clauses
hombre(francisco).
hombre(juan).
hombre(benito).
hombre(arcecio).
hombre(alex).
mujer(caterine).
mujer(isabel).
mujer(julia).
mujer(ana).
mujer(cristina).
mujer(laura).
mujer(silvia).
pariente(francisco,juan).
pariente(francisco,julia).
pariente(francisco,ana).
pariente(caterine,juan).
pariente(caterine,julia).
pariente(caterine,ana).
pariente(juan,arcecio).
pariente(juan,cristina).
pariente(isabel,arcecio).
pariente(isabel,cristina).
pariente(ana,alex).
pariente(ana,laura).
pariente(ana,silvia).
pariente(benito,alex).
pariente(benito,laura).
pariente(benito,silvia).
padre(X,Y):-hombre(X),pariente(X,Y).
madre(M,N):-mujer(M),pariente(M,N).
hijo(H,K):-hombre(H),pariente(K,H).
hija(L,M):-mujer(L),pariente(M,L).
hermano_de(H,O):-hombre(H),padre(L,H),padre(L,O),H<>O.
hermana_de(H,A):-mujer(H),madre(X,H),madre(X,A),H<>A.
abuelo(X,L):-hombre(X),padre(X,Y),pariente(Y,L).
abuela(Y,L):-mujer(Y),madre(Y,K),pariente(K,L).
tio_de(T,S):-hombre(T),hermano_de(T,P),madre(P,S) or
hombre(T),hermano(T,P),padre(P,S).
ancestro(A,P,L):-pariente(A,P),pariente(P,L).
Regresar
al indice
PARENTESCO 2
El siguiente programa esta
hecho en lenguaje de programación lógica Prolog y su
función es la de calcular cualquier parentesco en el árbol
genaológico de una familia utilizando un menú que le
permite escoger que parentescos quiere hayar, como por
ejemplo los hijos son de tal padre, el abuelo tiene los
siguientes nietos, los hermanos son y así sucesivamente.
domains
repla = symbol
perso=symbol
predicates
hombre(perso)
mujer(perso)
pariente(perso,perso)
padre(perso,perso)
madre(perso,perso)
hijo(perso,perso)
hija(perso,perso)
hermano(perso,perso)
hermana(perso,perso)
tio(perso,perso)
tia(perso,perso)
abuelo(perso,perso)
abuela(perso,perso)
ancestro(perso,perso)
run
case(string)
goal
run .
clauses
hombre(francisco).
hombre(juan).
hombre(benito).
hombre(arcecio).
hombre(alex).
mujer(caterine).
mujer(isabel).
mujer(julia).
mujer(ana).
mujer(laura).
mujer(silvia).
mujer(cristina).
pariente(francisco,juan).
pariente(francisco,isabel).
pariente(francisco,ana).
pariente(caterine,juan).
pariente(caterine,isabel).
pariente(caterine,ana).
pariente(juan,arcecio).
pariente(juan,cristina).
pariente(isabel,arcesio).
pariente(isabel,cristina).
pariente(ana,alex).
pariente(ana,laura).
pariente(ana,silvia).
pariente(benito,alex).
pariente(benito,laura).
pariente(benito,silvia).
run :- clearwindow, makewindow(2,3,14," UNIVERSIDAD
SANTIAGO DE CALI ",2,2,20,70),
write('\n','\n'),
write(" _____ MENU ______",'\n','\n'),
write(" Padre ..................... : P ",'\n'),
write(" Madre ..................... : M ",'\n'),
write(" Hermano ..................... : H ",'\n'),
write(" Hermana ..................... : K ",'\n'),
write(" Tio ..................... : T ",'\n'),
write(" Tia ..................... : W ",'\n'),
write(" Abuelo ..................... : A ",'\n'),
write(" Abuela ..................... : G ",'\n'),
write(" Salir ..................... : S ",'\n','\n'),
write(" Cual es su eleccion ............. : "),
readln(N),
write('\n'),
upper_lower(E,N),
case(E),
"E" = "Q".
run if run.
/***** REGLAS ******/
padre(X,Y):-hombre(X),pariente(X,Y).
madre(M,Y):-mujer(M),pariente(M,Y).
hijo(Y,X):-hombre(X),padre(Y,X).
hija(Y,X) :- mujer(Y),pariente(X,Y).
hermano(Y,Z):-hombre(Y),padre(X,Z),padre(X,Y),Y<>Z.
hermana(Y,Z):-mujer(Y),madre(X,Y),madre(X,Z),Y<>Z.
tio(X,Y):-hombre(X),hermano(X,Z),madre(Z,Y) or hombre(X),hermano(X,Z),padre(Z,Y).
tia(X,Y):-mujer(X),hermana(X,Z),madre(Z,Y) or mujer(X),hermana(X,Z),padre(Z,Y).
abuelo(Z,Y):-hombre(Z),padre(Z,X),padre(X,Y) or hombre(Z),padre(Z,X),madre(X,Y).
abuela(Z,Y):-mujer(Z),madre(Z,X),padre(X,Y) or mujer(Z),madre(Z,X),madre(X,Y).
ancestro(X,Y):-hombre(X),padre(X,Y) or hombre(X),tio(X,Y)
or hombre(X),abuelo(X,Y) or mujer(X),madre(X,Y) or mujer(X),tia(X,Y)
or mujer(X),abuela(X,Y).
/****************************************************************************/
/********************* GOALS INTERNOS
*************************/
case("P") :- clearwindow, padre(X,Y), write("
el padre es : ", X, " de " , Y),nl,
write(" ENTER ",'\174','\217', " para la
siguiente solucion ......."),
nl,readln(_), fail,readln(_).
case("M") :- clearwindow, madre(M,Y), write("
la madre es: ", M , " de :" , Y),nl, write("ENTER
",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("T") :- clearwindow, tio(X,Y), write("
El tio es : " , X , " de " ,Y ),nl, write("
ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("W") :- clearwindow, tia(X,Y), write("
La tia es : " , X , " de :" , Y),nl, write("
ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("A") :- clearwindow, abuelo(Z,Y), write("
El abuelo es : " , Z , " de " , Y),nl,
write("ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("G") :- clearwindow, abuela(Z,Y), write("
La abuela es: ", Z , " de: " , Y),nl,
write("ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("H") :- clearwindow, hermano(Y,Z), write("
El hermano es :" ,Y, " de : " , Z),nl,
write("ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("K") :- clearwindow, hermana(Y,Z), write("
La hermana es :" , Y, " de : ", Z ),nl,
write(" ENTER ",'\174','\217',
" para la siguiente solucion ......."), readln(_),
nl,fail.
case("S") :- clearwindow, cursor(10,15), write("
FIN DEL PROGRAMA .............."),
exit, nl.
Regresar
al indice
ARBOLES BINARIOS
/* ARBOLES BINARIOS */
arbol_binario(v).
arbol_binario(nodo(Raiz,Izq,Der)) :- arbol_binario(Izq),
arbol_binario(Der).
esta(X,nodo(X,Izq,Der)).
esta(X,nodo(Y,Izq,Der)) :- esta(X,Izq); esta(X,Der).
isomorfos(v,v).
isomorfos(nodo(X,I1,D1),nodo(X,I2,D2)) :- isomorfos(I1,I2),
isomorfos(D1,D2).
isomorfos(nodo(X,I1,D1),nodo(X,I2,D2)) :- isomorfos(I1,D2),
isomorfos(D1,I2).
sustituir(X,Y,v,v).
sustituir(X,Y,nodo(X,I1,D1),nodo(Y,I2,D2)) :- sustituir(X,Y,I1,I2),
sustituir(X,Y,D1,D2).
sustituir(X,Y,nodo(Z,I1,D1),nodo(Z,I2,D2)) :- X\=Z,
sustituir(X,Y,I1,I2),
sustituir(X,Y,D1,D2).
preorden(v,[]).
preorden(nodo(X,I,D),Xs) :- preorden(I,Ys), preorden(D,Zs),
concatena([X|Ys],Zs,Xs).
inorden(v,[]).
inorden(nodo(X,I,D),Xs) :- inorden(I,Ys), inorden(D,Zs),
concatena(Ys,[X|Zs],Xs).
postorden(v,[]).
postorden(nodo(X,I,D),Xs) :- postorden(I,Ys), postorden(D,Zs),
concatena(Ys,Ws,Xs),
concatena(Zs,[X],Ws).
concatena([],Ys,Ys).
concatena([X|Xs],Ys,[X|Zs]) :- concatena(Xs,Ys,Zs).
subarbol(X,X).
subarbol(Sub,nodo(Y,Izq,Der)) :- iguales(Sub,Izq);
iguales(Sub,Der);
subarbol(Sub,Izq);
subarbol(Sub,Der).
iguales(v,v).
iguales(nodo(X,I1,D1),nodo(X,I2,D2)) :- iguales(I1,I2),
iguales(D1,D2).
insertar(X,v,arbol(X,v,v)).
insertar(X,arbol(Y,I,D),arbol(Y,I1,D)) :- X<Y,
insertar(X,I,I1).
insertar(X,arbol(Y,I,D),arbol(Y,I,D1)) :- X>Y,
insertar(X,D,D1).
eliminar(X,arbol(X,v,v),v).
eliminar(X,arbol(Y,I,D1),arbol(Y,I,D2)) :- X>Y,
eliminar(X,D1,D2).
eliminar(X,arbol(Y,I1,D),arbol(Y,I2,D)) :- X<Y,
eliminar(X,I1,I2).
eliminar(X,arbol(X,I,D1),arbol(Z,I,D2)) :- vacio(I),minimo(D1,Z),
eliminar(Z,D1,D2).
eliminar(X,arbol(X,I1,D),arbol(Z,I2,D)) :- maximo(I1,Z),
eliminar(Z,I1,I2).
minimo(arbol(X,v,_),X).
minimo(arbol(X,I,D),Y) :- minimo(I,Y).
maximo(arbol(X,_,v),X).
maximo(arbol(X,I,D),Y) :- maximo(D,Y).
vacio(v).
Regresar
al indice
OPERACIONES CON
LISTAS
/* OPERACIONES CON LISTAS
*/
lista([]).
lista([X|Xs]) :- lista(Xs).
pertenece(X,[X|Xs]).
pertenece(X,[Y|Ys]) :- pertenece(X,Ys).
prefijo([],Xs).
prefijo([X|Xs],[X|Ys]) :- prefijo(Xs,Ys).
prefijo2(Xs,Ys) :- concatena(Xs,Ws,Ys).
sufijo(Xs,Xs).
sufijo(Xs,[Y|Ys]) :- sufijo(Xs,Ys).
sufijo2(Xs,Ys) :- concatena(Ws,Ys,Xs).
sublista(Xs,Ys) :- prefijo(Ws,Ys), sufijo(Xs,Ws).
sublista2(Xs,Ys) :- prefijo(Xs,Ws), sufijo(Ws,Ys).
sublista3(Xs,Ys) :- prefijo(Xs,Ys).
sublista3(Xs,[Y|Ys]) :-sublista(Xs,Ys).
sublista4(Xs,AsXsBs) :- concatena(As,XsBs,AsXsBs),
concatena(Xs,Bs,XsBs).
concatena([],Ys,Ys).
concatena([X|Xs],Ys,[X|Zs]) :- concatena(Xs,Ys,Zs).
pertenece2(X,Xs) :- sublista([X],Xs).
pertenece3(X,Ys) :- concatena(Ws,[X|Zs],Ys).
inversa([],[]).
inversa([X|Xs],Ys) :- inversa(Xs,Ws), concatena(Ws,[X],Ys).
inversa2(Xs,Ys) :- inversa2(Xs,[],Ys).
inversa2([X|Xs],Acc,Ys) :- inversa2(Xs,[X|Acc],Ys).
inversa2([],Ys,Ys).
adyacentes(X,Y,Zs) :- concatena(As,[X,Y|Bs],Zs).
longitud([],0).
longitud([X|Xs],N) :- longitud(Xs,M), N is M+1.
ultimo(Xs,Y) :- concatena(Ws,[Y],Xs).
borra([],X,[]).
borra([X|Xs],X,Ys) :- borra(Xs,X,Ys).
borra([X|Xs],Z,[X|Ys]) :- X\=Z, borra(Xs,Z,Ys).
borra_primer(X,[X|Xs],Xs).
borra_primer(X,[Y|Ys],[Y|Zs]) :- borra_primer(X,Ys,Zs).
ordenada([X]).
ordenada([X,Y|Ys]) :- X=<Y, ordenada([Y|Ys]).
permuta([],[]).
permuta(Xs,[Z|Zs]) :- borra_primer(Z,Xs,Ys), permuta(Ys,Zs).
inserta(X,Ys,Zs) :- borra_primer(X,Zs,Ys).
ordena(Xs,Ys) :- permuta(Xs,Ys), ordenada(Ys).
inserta2(X,[],[X]).
inserta2(X,[Y|Ys],[X,Y|Ys]) :- X=<Y.
inserta2(X,[Y|Ys],[Y|Zs]) :- X>Y, inserta2(X,Ys,Zs).
ordena2([],[]).
ordena2([X|Xs],Ys) :- ordena2(Xs,Zs), inserta2(X,Zs,Ys).
quicksort([],[]).
quicksort([X|Xs],Ys) :- partir(Xs,X,Menores,Mayores),
quicksort(Menores,Ax),
quicksort(Mayores,Bx),
concatena(Ax,[X|Bx],Ys).
partir([],_,[],[]).
partir([X|Xs],Y,[X|Menores],Mayores) :- X=<Y, partir(Xs,Y,Menores,Mayores).
partir([X|Xs],Y,Menores,[X|Mayores]) :- X>Y, partir(Xs,Y,Menores,Mayores).
sustituir(_,_,[],[]).
sustituir(X,Y,[X|Xs],[Y|Ys]) :- sustituir(X,Y,Xs,Ys).
sustituir(X,Y,[Z|Xs],[Z|Ys]) :- sustituir(X,Y,Xs,Ys).
no_repetir([],[]).
no_repetir([X|Xs],Ys) :- pertenece(X,Xs), no_repetir(Xs,Ys),
!.
no_repetir([X|Xs],[X|Ys]) :- not(pertenece(X,Xs)),
no_repetir(Xs,Ys).
mergesort([X],[X]) :- !.
mergesort([],[]).
mergesort(Xs,Ys) :- separa(Xs,Ws,Zs),
mergesort(Ws,Ws2),
mergesort(Zs,Zs2),
junta(Ws2,Zs2,Ys).
separa([],[],[]).
separa([X],[X],[]).
separa([X,Y|Ys],[X|Xs],[Y|Zs]) :- separa(Ys,Xs,Zs).
junta(Xs,[],Xs).
junta([],Xs,Xs).
junta([X|Xs],[Y|Ys],[X|Zs]) :- X<Y, junta(Xs,[Y|Ys],Zs).
junta([X|Xs],[Y|Ys],[Y|Zs]) :- X>=Y, junta([X|Xs],Ys,Zs).
Regresar
al indice
SUCESIÓN DE NÚMEROS
NATURALES
/*SUCESION DE NATURALES*/
nat(cero).
nat(suc(X)) :- nat(X).
menor_igual(cero,X) :- nat(X).
menor_igual(suc(X),suc(Y)) :- menor_igual(X,Y).
suma(X,cero,X) :- nat(X).
suma(X,suc(Y),suc(Z)) :- suma(X,Y,Z).
resta(X,Y,Z) :- suma(Y,Z,X).
producto(X,cero,cero) :- nat(X).
producto(X,suc(Y),Z) :- producto(X,Y,W), suma(W,X,Z).
potencia(cero,suc(X),cero) :- nat(X).
potencia(X,cero,suc(cero)) :- nat(X).
potencia(X,suc(Y),Z) :- potencia(X,Y,W), producto(W,X,Z).
factorial(cero,suc(cero)).
factorial(suc(X),Y) :- factorial(X,W), producto(W,suc(X),Y).
minimo(suc(X),cero,cero) :- nat(X).
minimo(cero,suc(Y),cero) :- nat(Y).
minimo(suc(X),suc(Y),suc(Z)) :- minimo(X,Y,Z).
minimo2(X,Y,X) :- menor_igual(X,Y).
minimo2(X,Y,Y) :- menor_igual(Y,X).
modulo(X,X,cero) :- nat(X).
modulo(X,Y,X) :- menor(X,Y).
modulo(X,Y,Z) :- mayor(X,Y), resta(X,Y,W), modulo(W,Y,Z).
cociente(X,Y,cero) :- nat(X), nat(Y), menor(X,Y).
cociente(X,Y,suc(Z)) :- resta(X,Y,W), cociente(W,Y,Z).
menor(cero,suc(X)) :- nat(X).
menor(suc(X),suc(Y)) :- menor(X,Y).
mayor(X,Y) :- not(menor_igual(X,Y)).
ackermann(cero,N,suc(N)) :- nat(N).
ackermann(suc(M),cero,N) :- ackermann(M,suc(cero),N).
ackermann(suc(M),suc(N),P) :- ackermann(suc(M),N,Q),
ackermann(M,Q,P).
mcd(suc(X),cero,suc(X)) :- nat(X).
mcd(X,Y,Z) :- modulo(X,Y,W), mcd(Y,W,Z).
Regresar
al indice
PROBLEMA DE LAS 8
REINAS
El problema de las ocho
reinas consta de colocar ocho reinas en un tablero de
ajedrez (una cuadricula de 8x8) de tal forma que ninguna
reina este en posición de comer a otra reina. Una reina
puede comer a cualquier otra reina que esta en la misma
fila, columna o diagonal.
El planteamiento de fuerza bruta comprueba algunas
disposiciones que podemos destacar inmediatamente.
Solución: sabemos que dos reinas no pueden aparecer en
la misma fila. De este modo una solución siempre puede
representarse utilizando un vector P[1...8], donde P[i]
es la columna en la que esta situada la reina de la fila
i-esima y por tanto las posiciones reales de las reinas
vienen dadas por (1,P[1]),..(8,P[8]).
Decimos que el vector P es k-factible si ninguna de las
reinas de las posiciones (1,P[1]),(2,P[2],..(K,P[k]))
puede comer a otra reina de esas posiciones.

A continuación se muestra
una solución a este problema generalizado a N reinas en
Prolog.
/* PROBLEMA DE LAS N-REINAS */
reinas(N,Rs) :- rango(1,N,Ns), permuta(Ns,Rs), asalvo(Rs).
asalvo([R|Rs]) :- asalvo(Rs), not ataca(R,Rs).
asalvo([]).
ataca(R,Rs) :- ataca(R,1,Rs).
ataca(X,N,[Y|Ys]) :- X is Y+N; X is Y-N.
ataca(X,N,[Y|Ys]) :- N1 is N+1, ataca(X,N1,Ys).
permuta(Xs,[Z|Zs]) :- borra_primer(Z,Xs,Ys), permuta(Ys,Zs).
permuta([],[]).
borra_primer(X,[X|Xs],Xs).
borra_primer(X,[Y|Ys],[Y|Zs]) :- borra_primer(X,Ys,Zs).
rango(N,N,[N]).
rango(N,M,[N|Xs]) :- N<M, N1 is N+1, rango(N1,M,Xs).
Regresar
al indice
|