%Un pequeño programa con concurrencia real, pero a la vez simulando
%una empresa que presta un servicio de limpieza. Ejecutar los siguientes
%comandos para darse una idea de qué hace:
%> c(lt1).
%> lt1:start().
%> Ls=lt1:pisoBasico(), gestor ! Ls.
%Metodología:
% Diseño multiagente con elementos clasificados en gestores y trabajadores.
% Módulos para cada agente: para un gestor y un trabajador.
% Identificación de capacidades de cada agente.
% Creación o diseño de protocolos de comunicación...
% Identificación de restricciones físicas para la simulación.
-module(lt1).
-export([start/0,start1/1,start2/1,gestionar/2,pisoBasico/0,es_piso/1, limpiar/3,
tomar/2,omitir/2,
dividir/1,sleep/1,retardar/1,
caso/2]).
es_parOrdenado({A,B}) when
is_integer(A) and
is_integer(B) -> true.
es_piso([]) -> true;
es_piso([P|Ls]) -> es_parOrdenado(P), es_piso(Ls).
start() ->
register(gestor,spawn(lt1,gestionar,[0,0])),
start1(gestor),
start2(gestor).
%recibeRapido(trabajador1), recibeRapido(trabajador2)
%{trabajador1:6,trabajador2:3}
%gestionar(0,0) %servidor???
start1(Gestor) -> register(trabajador1,spawn(lt1,limpiar,[Gestor,trabajo1,6])).
start2(Gestor) -> register(trabajador2,spawn(lt1,limpiar,[Gestor,trabajo2,3])).
caso(N,M) ->
if
N>M -> io:format("hola",[]);
N==M -> io:format("hollaaa",[]);
N<M -> io:format("adios",[])
end.
sleep(T) ->
receive
after T -> true
end.
%AreaAsignada es la capacidad que un robot puede limpiar en términos de área.
%Por agregar, Id del trabajador
retardar([]) -> true;
retardar([_|Ls]) ->
sleep(5000),
retardar(Ls).
limpiar(Gestor,A,AreaAsignada) ->
receive
{segmento,Segmento,ProcesoSolicitante} ->
es_piso(Segmento),
retardar(Segmento),
io:format("~n Segmento de piso correcto y terminado~n~p~n",
[Segmento]),
Gestor ! {terminado,A,self()}, %Palabras o msg a trab.
limpiar(Gestor,A,AreaAsignada);
{verificar, AreaALimpiar,ProcesoSolicitante} when
(AreaALimpiar =< AreaAsignada) ->
ProcesoSolicitante ! {si,self()},
io:format("si~n",[]),
limpiar(Gestor,A,AreaAsignada);
{verificar, AreaALimpiar,ProcesoSolicitante} when
(AreaALimpiar > AreaAsignada)
->
ProcesoSolicitante ! {no,self()},
io:format("no~n",[]),
limpiar(Gestor,A,AreaAsignada);
{limpiar, AreaALimpiar,ProcesoSolicitante} when
(AreaALimpiar =< AreaAsignada) ->
ProcesoSolicitante ! {siPuedoLimpiar,self()},
io:format("sí puedo~n",[]),
AreaAsignadaNueva = AreaAsignada-AreaALimpiar,
limpiar(Gestor,A,AreaAsignadaNueva);
{limpiar, AreaALimpiar,ProcesoSolicitante} when
(AreaALimpiar > AreaAsignada)
->
ProcesoSolicitante ! {noPuedoLimpiar,self()},
io:format("no puedo~n",[]),
limpiar(Gestor,A,AreaAsignada);
{alto,ProcesoSolicitante} -> io:format("Hasta luego, fue un placer",[])
end.
pisoBasico() -> [{X,Y} || X <-lists:seq(1,3),Y <-lists:seq(1,3)].
%tomar(N,Ls)
tomar(0,_) -> [];
tomar(N,[A|Ls]) -> [A|tomar(N-1,Ls)].
omitir(0,Ls) -> Ls;
omitir(N,[_|Ls]) -> omitir(N-1,Ls).
dividir(Ls) ->
L=length(Ls),
Mitad=L div 2,
{tomar(Mitad,Ls),omitir(Mitad,Ls)}.
%Es una función asociada únicamente al gestor
gestionar(K1,K2) ->
% link(trabajador1),
if
(K1==0) and (K2==0) -> true;
(K1==0) and (K2==1) -> true;
(K1==1) and (K2==0) -> true;
(K1==1) and (K2==1) -> self() ! "TERMINADO!!!!~n"
end,
receive
{reporte,terminado,IdProceso} ->
io:format("Listo~n~p",[IdProceso]),
gestionar(K1,K2);
{Piso,IdProceso} ->
es_piso(Piso),
io:format("Piso a limpiar~n~p~n",[Piso]),
{A,B}=dividir(Piso),
% falta...
% verificar si lo puede hacer...
% si lo puede hacer se prodece con segmento...
trabajador1 ! {segmento, A, self()},
trabajador2 ! {segmento, B, self()},
% osito1@RieGau ! {segmento, A, self()},
% osito2@RieGau ! {segmento, B, self()},
gestionar(K1,K2);
{terminado,trabajo1,Id1} ->
NK1=1,
gestionar(NK1,K2);
{terminado,trabajo2,Id2} ->
NK2=1,
gestionar(K1,NK2);
listo -> io:format("Sí~n",[]),
gestionar(K1,K2);
alto -> io:format("Proceso gestor terminado~n",[])
end.
%Por hacer o concluir:
% a) La idea de separar este archivo en varios otros, cada uno abarcando la
% funcionalidad de un agente específico.
% b) La posibilidad de que los archivos separados sean trabajados por programadores
% diferentes, cada programador concentrándose en elaborar o un agente o inclusive
% partes de un agente (comunicación, --infrarrojo [código de barras], actuadores, etc.).
% jabber
% c) La conceptualización de que toda comunicación entre agentes remotamente ubicados
% entre sí es mediante paso de mensajes (incluso cuando es un mismo robot interno).
%
%Falta una función de parte de los trabajadores para darse conocer con id.
Compilé y corrí el código según las instrucciones de los comentarios, sin embargo al momento de correr el tercer comando (Ls=pisoBasico(), gestor ! Ls.) me marca el error: exception error: undefined sell command pisoBasico/0. ¿A alguno de ustedes ya le corrió el código?
ResponderEliminar