Conciencia Artificial (I)

The nature of consciousness | Wall Street International Magazine

La conciencia artificial o conciencia de la máquina es un campo relacionado con la robótica cognitiva que tiene como objetivo probar diferentes tipos de enfoques filosóficos relacionados con el estudio de la conciencia.

La conciencia en sí misma ha sido un tema de estudio y debate a lo largo de los siglos. Diferentes ramas de la ciencia y la filosofía han estado luchando por determinar dónde se origina la conciencia y qué características deben considerarse para llamar a un ser 'consciente'.

Uno de los más interesantes es el concepto de "awareness" que es un concepto en inglés que conforma la conciencia. La conciencia como una característica de un ser consciente es la capacidad de ser consciente de sí mismo en ciertos criterios (conciencia de agencia, conciencia de objetivo y conciencia sensoriomotora). En el cerebro ubicamos esta característica como una frecuencia medible (Alfa y Beta) (1). En cuanto a las ondas delta (0 a 3 Hrtz) son incompatibles con funciones conscientes como el aprendizaje o la memoria. Las cosas inanimadas no pueden tener conciencia, porque sólo los seres conscientes pueden ser inconscientes. (2)

Neuropsicología de la conciencia


La conciencia y todos los demás fenómenos mentales son el resultado de una serie de reacciones neurobiológicas dentro del cerebro. Cada estímulo externo o interno tiene que ser procesado dentro del cerebro en forma de sinapsis y estructuras neuronales para convertirse en parte de nuestra experiencia-conciencia viva. En este punto dejaremos claro que a la fecha no existe una teoría científica aprobada de dónde se origina la conciencia o cuáles son las características base del concepto, sino muchos enfoques que intentan explicar los fenómenos de la misma. Lo que está claro es qué tipos de seres son y no son seres conscientes y a qué nivel aproximado.

 Joynes (1990) señala la posibilidad de la existencia de un género humano capaz de hablar, juzgar, razonar e incluso capaz de resolver problemas con la falta de conciencia.


Inteligencia artificial y conciencia


 Podemos considerar una entidad como consciente si posee algún tipo de sistema de percepción de alto nivel que le permita supervisar los estados y procesos cognitivos de dicha entidad. Los procesos de supervisión pueden incluir: creencias, recuerdos, deseos, necesidades, metas, miedos y mucho más.

Armstrong (1968) indica que los procesos son conscientes si la entidad crea la creencia de tenerlo como resultado de la supervisión de primera mano en lugar de como reflejo de su propia conducta.

Nava-Rivera (2001) afirma que la inteligencia artificial deberá abordar la autopercepción para construir un yo capaz de autopercepción.

El juego de la vida: una hipótesis para continuar


The Game of Life es un autómata celular diseñado por el matemático británico John Horton Conway en 1970. Consiste en un mecanismo independiente, una vez iniciada su ejecución el juego se desarrollará por sí solo dependiendo de su estado inicial. No requiere mayor interacción. Los elementos del juego son 'células' que 'nacen' y 'mueren' dependiendo de unidades de tiempo discretas que pueden considerarse turnos. Están actualizando siguiendo estas reglas:

🔘Una célula muerta con exactamente 3 células vecinas vivas "nace" (es decir, en el próximo turno estará viva).
🔘Una célula viva con 2 o 3 células vecinas vivas sigue viva, de lo contrario muere (por "soledad" o "superpoblación").

El Juego de la Vida podría ser un experimento potencial para agregar mecanismos de conciencia de forma pasiva, no tanto como la visión por computadora o la robótica, sino más bien de una manera filosófico-matemática agregando mecanismos de IA para recolectar información de cada 'turno' en el juego y el computadora en sí (calor, nivel de potencia, hilos en ejecución) podríamos tener un experimento mínimo de un ser consciente básico.
 
 
 

1) Brain Waves - an overview | ScienceDirect Topics. (s. f.). Sciencedirect. Recovered 30 of july 2021, from https://www.sciencedirect.com/topics/agricultural-and-biological-sciences/brain-waves

 2)  Nava-Rivera, A. (2001). Neuropsicología de la conciencia (1.a ed., Vol. 1). Programa de Psicofisiología, Facultad de Psicología. U.N.A.M.

3) Armstrong, D.M. (1968). A Material Theory of Mind. Londres Routlidge Kijan Paul.  

4) Joynes, J. (1990) The origin of Consciousness of the bicameral Mind 2nd Ed. Boston Hougton Miffin.

 

Daemons de unix y casos prácticos con NetCore

How to make a UNIX/Linux 'daemon' - GIGAZINE

Menos que dioses (Sistema operativo, Kernel) pero más como mortales (programas), los Daemons de Unix, mal llamados demonios en español, son procesos/servicios en segundo plano que no requieren de interacción directa del usuario de sistema para ejecutarse, es decir no requieren indicaciones desde ninguna interfaz ni terminal. 

Los Daemons nos sirven cuando necesitamos un proceso recurrente que trabaje en silencio en nuestro ordenador. 

Algunos ejemplos prácticos podrían ser crear un programa que nos envíe un recordatorio o alerta de algún tema en específico cada tanto tiempo, o algo mas complejo como replicar datos locales de una base de datos a otra.

De igual forma podemos configurar los Daemons para que se ejecuten al arranque de sistema incluyéndolos en systemd.

Los Daemons trabajan a nivel sistema operativo, pudiendo ejecutar cualquier tipo de programa o instrucción que deseemos. En el presente caso utilizaremos NetCore para generar breves ejemplos.

NetCore es lo mejor de Microsoft para Linux, en el tiempo que lo he utilizado me ha parecido un esquema muy agradable para trabajar.

Para todo esto tendremos que haber configurado nuestro ordenador para poder ejecutar entornos NetCore.

 

1. Generar el programa  

Abrimos Visual Studio y el tipo de proyecto que elegiremos para crear es "Aplicación de Consola", verificando que tenga la opción de compatibilidad con Linux:

 Fig. 1) Proyecto a elegir en Visual Studio (Aplicación de consola multiplataforma)

En nuestro programa principal (Program.cs) tendremos una sencilla función cuyo propósito será escribir en un archivo al estilo log:

     private static void WriteLog(string msg)  
     {  
       Console.WriteLine(msg);  
         System.IO.Directory.CreateDirectory("/home/euclides/Replicator/Logs");  
         string strFile = "/home/euclides/Replicator/Logs/ReplicaLog-" + DateTime.Now.Date.ToString("dd-MM-yyyy") + ".txt";  
         bool fileExists = File.Exists(strFile);  
         if (fileExists)  
         {  
           using (StreamWriter sw = new StreamWriter(File.Open(strFile, FileMode.Append)))  
           {  
             sw.WriteLine(msg);  
           }  
         }  
         else  
         {  
           using (StreamWriter sw = new StreamWriter(File.Open(strFile, FileMode.OpenOrCreate)))  
           {  
             sw.WriteLine(msg);  
           }  
         }  
     }  



De igual forma añadiremos un temporizador para controlar los tiempos en los cuales se ejecute nuestra función:

     private Timer _tmEscritura = null;  
     private AutoResetEvent _autoEvent = null;  
     private void StartTimer()  
     {  
       try  
       {  
         WriteLog("Configurando temporizador");  
         //dueTime muestra cuando se realizará la primera ejecución (1000 MS),  
         //period es después de ello cada cuanto tiempo (timespan.fromminutes)  
         _autoEvent = new AutoResetEvent(true);  
         _tmEscritura = new Timer(WriteLog("La hora es: " + DateTime.Now.ToString()), _autoEvent, 1000, (int)TimeSpan.FromMinutes(5).TotalMilliseconds);  
         WriteLog("Fin de configuracion de temporizador");  
         while (true) ; //Instrucción para que prevalezca en ejecución  
       }  
       catch (Exception ex)  
       {  
         WriteLog("ERROR DE EJECUCIÓN: " + ex.Message);  
       }  
     }  



Finalmente, nuestro hilo principal quedaría así con el temporizador:


     private static void Main(string[] args)  
     {  
       WriteLog("INICIO DE EJECUCIÓN");  
       Program p = new Program();  
       p.StartTimer();  
     }  



Una vez hecho esto compilamos en Release, y publicamos con compatibilidad Linux. Lo cargamos por FTP al directorio que deseemos y le damos permisos de escritura, lectura y ejecución.



2. Crear el Daemon

Para crear el Daemon escribiremos un archivo de texto con extensión .service en el cual indicaremos la ubicación de nuestro programa ejecutable y la descripción del mismo, así como el nombre mediante el cual lo identificaremos y el usuario o grupo de usuarios que tienen permiso de manipularlo.

 [Unit]  
 Description=Programa de escritura de logs de hora con temporizador  
 [Service]  
 # systemd will run this executable to start the service  
 ExecStart=/home/euclides/WriteLog/WriteLog  
 # to query logs using journalctl, set a logical name here  
 SyslogIdentifier=WriteLog  
 # Use your username to keep things simple.  
 # If you pick a different user, make sure dotnet and all permissions are set correctly to run the app  
 # To update permissions, use 'chown yourusername -R /srv/HelloWorld' to take ownership of the folder and files,  
 #    Use 'chmod +x /srv/HelloWorld/HelloWorld' to allow execution of the executable file  
 User=euclides 
 [Install]  
 WantedBy=multi-user.target  


Este archivo deberá almacenarse en la ruta /etc/systemd/system/ 

Los últimos pasos para tener nuestro Daemon en ejecución son recargar la pila de daemons y habilitarlo al arranque del sistema operativo mediante los siguientes comandos:


 //Recarga la pila de daemons  
 sudo systemctl daemon-reload  
 //Habilita la ejecución al arranque del sistema   
 sudo systemctl enable WriteLog.service  
 //Inicia el daemon  
 sudo systemctl start WriteLog.service  


Listo, hemos creado un Daemon de Unix en NetCore con un temporizador y función para escritura de archivos al estilo log.


Patrones de diseño: Singleton + Ejemplos en C#

Que son los patrones de diseño


Los patrones de diseño formalmente resultan ser una solución a problemas propensos a tratarse de forma similar. Es decir, que una solución fija les puede calzar. No es obligatorio utilizar un patrón de diseño para resolver una problemática dada, pero en algunos casos resulta ser lo más sensato ya que acorta el tiempo o los recursos necesarios para ejecutar la solución deseada.


Singleton

Singleton es un patrón que garantiza la existencia de una instancia única para determinada clase, es decir, que en memoria no existirá otra del mismo tipo hasta que la primera haya finalizado su ejecución. Esto nos ayuda cuando no deseamos permitir a nuestros usuarios ejecutar más de una vez el mismo programa.

Utilizando singleton restringimos el numero de instancias del mismo tipo en memoria activas a solo una. 

Ejemplo en C#

 Singleton tradicional

En el siguiente ejemplo generamos un candado para conocer el estatus de la ejecución y creamos formalmente la clase singleton para detectar y obtener el estatus de la instancia.

 public sealed class Singleton  
 {  
   private static volatile Singleton instance;  
   private static object syncRoot = new Object();  
   private Singleton()  
   {  
     System.Windows.Forms.MessageBox.Show("Nuevo Singleton");  
   }  
   public static Singleton GetInstance  
   {  
     get  
     {  
       if (instance == null)  
       {  
         lock(syncRoot)  
         {  
           if (instance == null)  
           instance = new Singleton();  
         }  
       }  
       return instance;  
     }  
   }  
 }  

 

 Validación en memoria mediante Mutex

En este caso modificamos la clase Program.cs de una solución de Winforms en visual studio. Mediante la clase Mutex buscamos si ya existe en memoria una instancia del mismo programa y denegamos una nueva ejecución

     [STAThread]  
     private static void Main()  
     {  
       bool instanceCountOne = false;  
       using (Mutex mtex = new Mutex(true, "Mi Programa", out instanceCountOne))  
       {  
         if (instanceCountOne)  
         {  
           Application.EnableVisualStyles();  
           Application.SetCompatibleTextRenderingDefault(false);  
           Application.Run(new FrmPrincipal());  
         }  
         else  
         {  
           MessageBox.Show("Ya se está ejecutando.", "Mi Programa");  
         }  
       }  
     }  

 

Conclusión

Hemos visto dos formas de implementar un mecanismo singleton en C# así como su utilidad básica: solo permitir una instancia de la misma clase.