Saltar al contenido

Programación declarativa: Interfaz en lenguaje natural para un robot en SWI Prolog

Para los que todavía tienen pendientes la asignatura Programación Declarativa como los que estén aprendiendo Prolog, os presento mi solución  a la práctica final. Quiero resaltar el hecho de que os la presento para comparar vuestra solución con la aquí proporcionada, no para que la copiéis sin más. Para los que no tengan la asignatura pueden tomárselo como un ejercicio práctico a partir del cual se proporciona una posible solución de entre todas las que existen.


% DECLARACIÓN DE PREDICADOS DINÁMICOS
 
:-dynamic conjuntoDeMesas/1.
:-dynamic brazos/2.
:-dynamic incompatible/2.
:-dynamic bandejas/1.
:-dynamic orden/1.
 
 
% OPERADORES UNARIOS
 
:-op(100,fy,[el]).
:-op(100,fy,[incompatible]).
:-op(200,xf,[cercano]).
 
 
% OPERADORES BINARIOS
 
:-op(150,xfy,[coge_en]).
:-op(150,xfy,[coge]).
:-op(150,xfy,[deposita]).
:-op(150,xfy,[sobre]).
:-op(150,xfy,[deposita_en]).
:-op(250,xfy,[de]).
:-op(300,xfy,[hasta_encontrar]).
:-op(200,xfy,[en]).
 
 
% BANDEJAS DE LOS BRAZOS ROBOTIZADOS
% [ [ [forma,color],[forma,color] ],[ [forma,color] ] ]
% | | |———–| |———–| | | |———–| | |
% | |    Objeto 1      Objeto 2   | |    Objeto 1   | |
% | |—————————–| |—————| |
% |        Bandeja brazo 1           Bandeja brazo 2  |
% |—————————————————|
%                        Bandejas
 
bandejas([[[cubo,rojo],[esfera,rojo],[piramide,rojo],[]],[[piramide,azul],[cubo,azul],[]]]).
 
 
% BRAZOS DE LOS ROBOTS
% brazo(id_robot,mesa)
 
brazos(1,1).
brazos(2,2).
 
 
% CONJUNTO DE MESAS
% [ [ [ [forma,color],[forma,color] ],[ [forma,color] ] ],[ [ [forma,color] ],[ [forma,color],[forma,color] ] ] ]
% | | | |———–| |———–| | | |———–| | | | | |———–| | | |———–| |———–| | | |
% | | |    Objeto 1     Objeto 2    | |    Objeto 1   | | | |   Objeto 1    | |    Objeto 1      Objeto 2   | | |
% | | |—————————–| |—————| | | |—————| |—————————–| | |
% | |            Montón 1                  Montón 2     | |      Montón 1                 Montón 2            | |
% | |—————————————————| |—————————————————| |
% |                        Mesa 1                                                Mesa 2                         |
% |————————————————————————————————————-|
%                                                 conjuntoDeMesas
 
conjuntoDeMesas([[[[piramide,blanco],[piramide,rojo]],[[piramide,blanco],[cubo,azul]],[[cubo,blanco],[cubo,rojo]]],
                 [[[esfera,blanco],[cubo,rojo],[cubo,rojo],[cubo,blanco]],[[piramide,azul],[esfera,blanco]],[[piramide,blanco],[piramide,rojo]]]]).
 
 
% INCOMPATIBILIDADES…
% incompatible(objeto_superio,objeto_inferior)
 
 
% …DE FORMA
% incompatible(piramide, piramide).
% incompatible(esfera,cubo).
% incompatible(cubo,esfera).
% incompatible(esfera, esfera).
% incompatible(azul,azul).
 
 
% …DE COLOR
% incompatible(rojo,azul).
 
 
% PREDICADO AUXILIAR ELIMINAR CABEZA BANDEJA
 
eliminarCabezaBandeja(1,[[_|Cola]|Restobandejas],[Cola|Restobandejas]).
eliminarCabezaBandeja(2,[Car|Cdr],[Car|R]):-eliminarCabezaBandeja(1,Cdr,R).
 
 
% PREDICADO AUXILIAR DE COMPROBACIÓN DE COMPATIBILIDAD
 
compatibilidad([_|_],[]):-!.
compatibilidad([Objeto|_],[Car|_]):-incompatible(Objeto,Car),!,fail.
compatibilidad([_|[Cdrobjeto|_]],[_|[Cdr|_]]):-incompatible(Cdrobjeto,Cdr),!,fail.
compatibilidad([_|_],[_|_]).
 
 
% PREDICADO AUXILIAR ESTRUCTURA DE DECISIÓN IF THEN ELSE
 
ifThenElse(P,Q,_):-P,!,Q.
ifThenElse(_,_,R):-R.
 
 
% PREDICADO AUXILIAR QUE MUESTRA EL UNIVERSO
 
mostrarUniverso(E):-bandejas(Bandejas),brazos(1,M1),brazos(2,M2),mostrarConjuntoDeMesas(E),mostrarBandejas(Bandejas),mostrarBrazos(M1,M2).
 
recorrerConjuntoDeMesas([]):-!.
recorrerConjuntoDeMesas([Car|[]],I):-In is I+1,write(‘nLa mesa ‘),write(I),write(‘ contiene ‘),write(Car),write(‘n’),!.
recorrerConjuntoDeMesas([Car|Cdr],I):-In is I+1,write(‘nLa mesa : ‘),write(I),write(‘ contiene ‘),write(Car),recorrerConjuntoDeMesas(Cdr,In).
 
mostrarConjuntoDeMesas(E):-write(‘nSituación del conjunto de mesas: ‘),recorrerConjuntoDeMesas(E,1).
 
recorrerBandejas([]):-!.
recorrerBandejas([Car|[]],I):-In is I+1,write(‘nLa bandeja ‘),write(I),write(‘ contiene ‘),write(Car),write(‘n’),!.
recorrerBandejas([Car|Cdr],I):-In is I+1,write(‘nLa bandeja ‘),write(I),write(‘ contiene ‘),write(Car),recorrerBandejas(Cdr,In).
 
mostrarBandejas(Bandejas):-write(‘nSituación de las bandejas: ‘),recorrerBandejas(Bandejas,1).
 
mostrarBrazos(M1,M2):-write(‘nSituación de los brazos: ‘),
                      write(‘nEl brazo 1 está en mesa ‘),write(M1),
                      write(‘nEl brazo 2 está en mesa ‘),write(M2),write(‘n’).
 
 
% PREDICADOS DE COMANDO «el BRAZO coge FORMA/COLOR/OBJETO en MONTON de MESA»
 
cogerObjeto([N1|Cdr0],Objeto,Cdr0):-ifThenElse(N1=Objeto,true,fail).
 
seleccionarMonton([M1|CdrM],1,Objeto,[Res|CdrM]):-cogerObjeto(M1,Objeto,Res).
seleccionarMonton([M1|CdrM],1,Objeto,[M1|CdrM]):-write(‘nERROR: El objeto no esta en la cima del monton o no existe.’),!.
seleccionarMonton([M1|CdrM],Monton1,Objeto,[M1|Res]):-MontonM is Monton1-1,
                                                      seleccionarMonton(CdrM,MontonM,Objeto,Res).
seleccionarMesa([Car|Cdr],Brazo1,1,Monton1,Objeto,[R|Cdr]):-seleccionarMonton(Car,Monton1,Objeto,R).
seleccionarMesa([Car|Cdr],Brazo1,Mesa1,Monton1,Objeto,[Car|R]):-MesaM is Mesa1-1,seleccionarMesa(Cdr,Brazo1,MesaM,Monton1,Objeto,R).
 
pasarALista(Objeto,[Objeto]):-atomic(Objeto),Objeto==[].
 
agregarObjeto(Objeto,Car,[Objeto|Car]).
 
introducirObjetoEnBandeja(1,Objeto,[Car|Cdr],[Res|Cdr]):-agregarObjeto(Objeto,Car,Res),!.
introducirObjetoEnBandeja(Bolsa1,Objeto,[Car|Cdr],[Car|Nueva]):-BolsaCont is Bolsa1-1,introducirObjetoEnBandeja(BolsaCont,Objeto,Cdr,Nueva).
 
situarBrazo(X,Mesa):-retract(brazos(X,_)),assert(brazos(X,Mesa)).
 
comando(el Brazo1 coge [Forma,Color] en Monton1 de Mesa1):-conjuntoDeMesas(X),mostrarUniverso(X),
                                                           pasarALista(Color,LColor),
                                                           seleccionarMesa(X,Brazo1,Mesa1,Monton1,[Forma|LColor],NuevoconjuntoDeMesas),
                                                           ifThenElse(X=NuevoconjuntoDeMesas,(mostrarUniverso(NuevoconjuntoDeMesas),write(‘nERROR: No se ha podido coger el objeto.’),fail),true),
                                                           retract(conjuntoDeMesas(E)),
                                                           assert(conjuntoDeMesas(NuevoconjuntoDeMesas)),
                                                           write(‘nSE HA COGIDO EL OBJETO:n———————–‘),!,
                                                           situarBrazo(Brazo1,Mesa1),
                                                           bandejas(Vieja),
                                                           introducirObjetoEnBandeja(Brazo1,[Forma|LColor],Vieja,Nueva),
                                                           retract(bandejas(Vieja)),
                                                           assert(bandejas(Nueva)),
                                                           mostrarUniverso(NuevoconjuntoDeMesas).
 
 
% PREDICADOS DE COMANDO «el BRAZO deposita FORMA/COLOR/OBJETO en MONTON de MESA»
 
cogerObjetoCima([Car|Cdr],Cdr,Objeto):-ifThenElse(Car=Objeto,true,(write(‘nERROR: El objeto a depositar no se encuentra en la cima de la bandeja’),fail)).
 
mirarEnBandeja(1,[Car|Cdr],[Res|Cdr],Objeto):-cogerObjetoCima(Car,Res,Objeto).
mirarEnBandeja(Brazo,[Car|Cdr],[Car|Res],Objeto):-BrazoR is Brazo-1,mirarEnBandeja(BrazoR,Cdr,Res,Objeto).
 
noIncompatible(Objeto,Car):-compatibilidad(Objeto,Car).
 
noIncompatibleObjeto([Car|Cdr],Objeto):-noIncompatible(Objeto,Car).
 
depositarObjeto(ListaObj,Objeto,[Objeto|ListaObj]):-ifThenElse(noIncompatibleObjeto(ListaObj,Objeto),true,write(‘nERROR: No se puede depositar el objeto debido a una incompatibilidad.’)).
 
depositarObjetoEnMonton([Car|Cdr],Objeto,1,[Res|Cdr]):-depositarObjeto(Car,Objeto,Res).
depositarObjetoEnMonton([Car|Cdr],Objeto,Monton,[Car|Res]):-MontonR is Monton-1,depositarObjetoEnMonton(Cdr,Objeto,MontonR,Res).
 
depositarObjetoEnMesa([Car|Cdr],Objeto,Monton,1,[Res|Cdr]):-depositarObjetoEnMonton(Car,Objeto,Monton,Res).
depositarObjetoEnMesa([Car|Cdr],Objeto,Monton,Mesa,[Car|Res]):-MesaR is Mesa-1,depositarObjetoEnMesa(Cdr,Objeto,Monton,MesaR,Res).
 
actualizarBandeja(BolsaVieja,BolsaNueva):-retract(bandejas(BolsaVieja)),assert(bandejas(BolsaNueva)).
 
comando(el Brazo deposita [Forma,Color] en Monton de Mesa):-conjuntoDeMesas(X),mostrarUniverso(X),
                                                            bandejas(Bandeja),
                                                            pasarALista(Color,LColor),
                                                            mirarEnBandeja(Brazo,Bandeja,BandejaR,[Forma|LColor]),
                                                            situarBrazo(Brazo,Mesa),
                                                            ifThenElse(Bandeja=BandejaR,fail,true),
                                                            actualizarBandeja(Bandeja,BandejaR),
                                                            depositarObjetoEnMesa(X,[Forma|LColor],Monton,Mesa,NuevoX),
                                                            write(‘nSE HA DEPOSITADO EL OBJETO:n—————————‘),
                                                            mostrarUniverso(NuevoX).
 
 
% PREDICADO DE COMANDO «incompatible OBJETO/COLOR/FORMA sobre OBJETO/COLOR/FORMA»
 
comando(incompatible FormaColor1 sobre FormaColor2):-assert(incompatible(FormaColor1,FormaColor2)),write(‘nSe ha añadido una nueva incompatibilidad: ‘),
                                                     write(FormaColor1),write(‘ sobre ‘),write(FormaColor2).
 
 
% PREDICADOS DE COMANDO «el BRAZO coge_en MONTON de MESA hasta_encontrar FORMA/COLOR/OBJETO»
 
objetoEncontrado(Brazo,Objeto):-bandejas(Bvieja),introducirObjetoEnBandeja(Brazo,Objeto,Bvieja,Bnueva),
                                actualizarBandeja(Bvieja,Bnueva),
                                write(‘nObjeto encontrado.n’).
 
cogerObjetoHastaEncontrar(Brazo,[],Objeto,[]):-!.
cogerObjetoHastaEncontrar(Brazo,[Car|Cdr],Objeto,Cdr):-ifThenElse(Car=Objeto,objetoEncontrado(Brazo,Objeto),fail).
cogerObjetoHastaEncontrar(Brazo,[CimaM|RestoM],Objeto,R):-bandejas(Bvieja),
                                                          introducirObjetoEnBandeja(Brazo,CimaM,Bvieja,Bnueva),
                                                          actualizarBandeja(Bvieja,Bnueva),
                                                          cogerObjetoHastaEncontrar(Brazo,RestoM,Objeto,R).
 
seleccionarMontonHastaEncontrar([M1|CdrM],Brazo,1,Objeto,[Res|CdrM]):-cogerObjetoHastaEncontrar(Brazo,M1,Objeto,Res).
seleccionarMontonHastaEncontrar([],Brazo,1,Objeto,[M1|CdrM]):-write(‘nWARNING: El objeto no ha sido encontrado en el montón. Éste se ha vaciado por completo.’),fail.
seleccionarMontonHastaEncontrar([M1|CdrM],Brazo,Monton,Objeto,[M1|Res]):-MontonM is Monton-1,seleccionarMontonHastaEncontrar(CdrM,Brazo,MontonM,Objeto,Res).
 
cogerHastaEncontrar([Car|Cdr],Brazo,1,Monton,Objeto,[R|Cdr]):-seleccionarMontonHastaEncontrar(Car,Brazo,Monton,Objeto,R).
cogerHastaEncontrar([Car|Cdr],Brazo,Mesa,Monton,Objeto,[Car|R]):-MesaM is Mesa-1,cogerHastaEncontrar(Cdr,Brazo,MesaM,Monton,Objeto,R).
 
comando(el Brazo coge_en Monton de Mesa hasta_encontrar [Forma,Color]):-conjuntoDeMesas(ViejoConjuntoDeMesas),mostrarUniverso(ViejoConjuntoDeMesas),
                                                                        pasarALista(Color,LColor),
                                                                        situarBrazo(Brazo,Mesa),
                                                                        cogerHastaEncontrar(ViejoConjuntoDeMesas,Brazo,Mesa,Monton,[Forma|LColor],NuevoConjuntoDeMesas),
                                                                        ifThenElse(ViejoConjuntoDeMesas=NuevoConjuntoDeMesas,fail,true),
                                                                        retract(conjuntoDeMesas(ViejoConjuntoDeMesas)),assert(conjuntoDeMesas(NuevoConjuntoDeMesas)),
                                                                        conjuntoDeMesas(Nuevo),
                                                                        write(‘nSE HAN COGIDO OBJETOS:n—————————‘),
                                                                        mostrarUniverso(Nuevo).
 
 
% PREDICADOS DE COMANDO «el BRAZO deposita_en MONTON de MESA hasta_encontrar FORMA/COLOR/OBJETO»
 
notIncompatible(Objeto,Car):-compatibilidad(Objeto,Car).
notIncompatible(_,_):-write(‘nSe ha detectado una incompatibilidad en un movimiento’),fail.
 
noEsIncompatible(Objeto,[CarMonton|CdrMonton]):-notIncompatible(Objeto,CarMonton),!.
 
depositaHastaEncontrar(NumBandeja,[[]],MontonEsc,_,MontonEsc):-write(‘nWARNING: La bandeja se ha vaciado y no se ha encontrado el objeto.n’).
depositaHastaEncontrar(NumBandeja,[CarBandeja|CdrBandeja],MontonEsc,Objeto,MontonEsc):-not(noEsIncompatible(CarBandeja,MontonEsc)),!.
depositaHastaEncontrar(NumBandeja,[CarBandeja|CdrBandeja],MontonEsc,Objeto,[CarBandeja|MontonEsc]):-ifThenElse(CarBandeja=Objeto,(bandejas(B),retract(bandejas(B)),eliminarCabezaBandeja(NumBandeja,B,Result),assert(bandejas(Result))),fail),!.
depositaHastaEncontrar(NumBandeja,[CarBandeja|CdrBandeja],MontonEsc,Objeto,R):-bandejas(B),retract(bandejas(B)), eliminarCabezaBandeja(NumBandeja,B,Result),assert(bandejas(Result)),
                                                                               depositaHastaEncontrar(NumBandeja,CdrBandeja,[CarBandeja|MontonEsc],Objeto,R).
                                                                               
% Función que elige la bandeja que debemos vaciar
seleccionarBandeja(NumBandeja,1,[Bcar|Bcdr],MontonEsc,Objeto,R):-depositaHastaEncontrar(NumBandeja,Bcar,MontonEsc,Objeto,R),!.
seleccionarBandeja(NumBandeja,Brazo,[Bcar|Bcdr],MontonEsc,Objeto,R):-BrazoR is Brazo-1,seleccionarBandeja(NumBandeja,BrazoR,Bcdr,MontonEsc,Objeto,R).
 
irAMontonDepositar(Brazo,B,[Car|Cdr],1,Objeto,[R|Cdr]):-seleccionarBandeja(Brazo,Brazo,B,Car,Objeto,R),!.
irAMontonDepositar(Brazo,B,[Car|Cdr],M,Objeto,[Car|R]):-MontonR is M-1,irAMontonDepositar(Brazo,B,Cdr,MontonR,Objeto,R).
 
irAMesaDepositar(Brazo,[Car|Cdr],B,1,Monton,Objeto,[R|Cdr]):-irAMontonDepositar(Brazo,B,Car,Monton,Objeto,R),!.
irAMesaDepositar(Brazo,[Car|Cdr],B,Mesa1,Monton,Objeto,[Car|R]):-Mesa is Mesa1-1,irAMesaDepositar(Brazo,Cdr,B,Mesa,Monton,Objeto,R).
 
comando(el Brazo deposita_en Monton de Mesa hasta_encontrar [Forma,Color]):-bandejas(ViejasBandejas),%conjuntoDeMesas(X),mostrarUniverso(X),
                                                                            pasarALista(Color,ColorLista),
                                                                            situarBrazo(Brazo,Mesa),
                                                                            conjuntoDeMesas(Viejo),mostrarUniverso(Viejo),
                                                                            irAMesaDepositar(Brazo,Viejo,ViejasBandejas,Mesa,Monton,[Forma|ColorLista],Nuevo),
                                                                            retract(conjuntoDeMesas(Viejo)),asserta(conjuntoDeMesas(Nuevo)),
                                                                            conjuntoDeMesas(E),
                                                                            write(‘nOBJETOS DE BANDEJA DEPOSITADOS:n—————————‘),
                                                                            mostrarUniverso(E).
 
 
% PREDICADOS DE COMANDO «BRAZO coge OBJETO/ESFERA/COLOR cercano»
 
longitud([],0).
longitud([_|Cdr],N):-longitud(Cdr,N0),N is N0 + 1.
 
% Predicado que actualiza el conjuntoDeMesas después de coger un objeto cercano
cogerCercanoConjuntoDeMesas([ConjuntoDeMesasCar|ConjuntoDeMesasCdr],Mesa,Resto,[Car|ConjuntoDeMesasCdr]):-ifThenElse(ConjuntoDeMesasCar=Mesa,(true,Car=Resto),fail),!.
cogerCercanoConjuntoDeMesas([ConjuntoDeMesasCar|ConjuntoDeMesasCdr],Mesa,Resto,[ConjuntoDeMesasCar|R]):-cogerCercanoConjuntoDeMesas(ConjuntoDeMesasCdr,Mesa,Resto,R).
 
% Predicado que coge el objeto del montón y los inserta en la bandeja
cogerObjetoCercano(0,Lista,_,Lista):-!,fail.
cogerObjetoCercano(-1,Lista,_,Lista):-!.
 
% Si devolvió true tenemos que borrar Car del montón
cogerObjetoCercano(Brazo,[Car|Cdr],Objeto,R):-ifThenElse(Objeto=Car,(bandejas(X),(introducirObjetoEnBandeja(Brazo,Car,X,NuevaLista),retract(bandejas(X)),
                                              assert(bandejas(NuevaLista))),cogerObjetoCercano(-1,Cdr,Objeto,R)),
                                              cogerObjetoCercano(0,[Car|Cdr],Objeto,R)).
 
% Predicado que quita de montón Objeto, si cogerObjeto_sacar dio true
irAMontonCercano(Brazo,[Car|Cdr],Objeto,[R|Cdr]):-cogerObjetoCercano(Brazo,Car,Objeto,R),!.
irAMontonCercano(Brazo,[Car|Cdr],Objeto,[Car|R]):-irAMontonCercano(Brazo,Cdr,Objeto,R).
 
% Predicado que busca en las mesas donde está el objeto más cercano a un brazo
irAMesaCercana(_,[],_,_,_,_,_,_,_):-!,fail.
irAMesaCercana(Brazo,X,X,Asig,0,Mesa,Mesa,Objeto,R):-longitud(X,N),Pos is N-1,irAMesaCercana(Brazo,X,X,Asig,Pos,Pos,Pos,Objeto,R).
irAMesaCercana(Brazo,X,X,Asig,0,Mesa,Mesa,Objeto,R):-longitud(X,N),Pos is N-1,irAMesaCercana(Brazo,X,X,Asig,Pos,Pos,Pos,Objeto,R).
irAMesaCercana(Brazo,[Car|Cdr],X,Asig,_,1,_,Objeto,[Res|Cdr]):-irAMontonCercano(Brazo,Car,Objeto,R),
                                                               situarBrazo(Brazo,Asig),cogerCercanoConjuntoDeMesas(X,Car,R,Res),!.
irAMesaCercana(Brazo,[_|_],X,_,Mesa,1,AlmMesa,Objeto,R):-longitud(X,N),ifThenElse(N=AlmMesa,Mesa3 is AlmMesa-1,Mesa3 is AlmMesa+1),
                                                         ifThenElse(Mesa>AlmMesa,Mesa3 is AlmMesa-1,Mesa4 is AlmMesa – 1),
                                                         irAMesaCercana(Brazo,X,X,Mesa3,AlmMesa,Mesa3,Mesa4,Objeto,R),!.
irAMesaCercana(Brazo,[_|_],X,_,_,1,AlmMesa,Objeto,R):-Mesa1=AlmMesa,irAMesaCercana(Brazo,X,X,Mesa1,Mesa1,Mesa1,Mesa1,Objeto,R),!.
irAMesaCercana(Brazo,[_|Cdr],X,Asig,Mesa,Mesa1,AlmMesa,Objeto,R):-Mesa2 is Mesa1-1,irAMesaCercana(Brazo,Cdr,X,Asig,Mesa,Mesa2,AlmMesa,Objeto,R),!.
 
comando(Brazo coge [Forma,Color] cercano):-conjuntoDeMesas(E),mostrarUniverso(E),
                                           pasarALista(Color,ColorLista),
                                           brazos(Brazo,Mesa),
                                           irAMesaCercana(Brazo,E,E,Mesa,Mesa,Mesa,Mesa,[Forma|ColorLista],[Rcar|_]),
                                           ifThenElse(E=Rcar,fail,(retract(conjuntoDeMesas(E)),asserta(conjuntoDeMesas(Rcar)))),
                                           conjuntoDeMesas(Esc),mostrarUniverso(Esc).
 
% PREDICADOS DE INTERFAZ DE USUARIO
 
principal:-write(‘n     INTERFAZ EN LENGUAJE NATURAL PARA UN ROBOTn     ———————————————-n     Escriba ayuda en caso de dudas o salir.n’),loop,!.
 
loop:-repeat,leerOrden(X),procesarOrden(X),!.
 
leerOrden(X):-repeat,write(‘n> ‘),read(X),!.
 
procesarOrden(salir):-halt.
procesarOrden(ayuda):-write(‘n     AYUDA:’),
                      write(‘n     ———————————————————————–‘),
                      write(‘n   – el BRAZO coge [forma,color] en MONTON de MESA’),
                      write(‘n   – el BRAZO deposita [forma,color] en MONTON de MESA’),
                      write(‘n   – el BRAZO coge_en MONTON de MESA hasta_encontrar [forma,color]’),
                      write(‘n   – el BRAZO deposita_en MONTON de MESA hasta_encontrar [forma,color]’),
                      write(‘n   – BRAZO coge [forma,color] cercano’),
                      write(‘n   – incompatible FORMA/COLOR/OBJETO sobre FORMA/COLOR/OBJETO’),
                      write(‘n   – ayuda’),
                      write(‘n   – salirn’),loop,!.
procesarOrden(X):-comando(X),fail.


Publicado enProgramación de alto nivelProgramación declarativa