<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : Inteligencia Artificial, C Sharp</title><link>http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/C+Sharp/default.aspx</link><description>Tags: Inteligencia Artificial, C Sharp</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Inteligencia Artifical en C# (1) Primeros Agentes</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/21/inteligencia-artifical-en-c-1-primeros-agentes.aspx</link><pubDate>Sun, 21 Apr 2013 09:04:59 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827934</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827934</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/21/inteligencia-artifical-en-c-1-primeros-agentes.aspx#comments</comments><description>&lt;p&gt;Ayer comencé a implementar ejemplos del libro Artificial Intelligence: A Modern Approach, de &lt;a href="http://www.cs.berkeley.edu/~russell"&gt;Stuart Russell&lt;/a&gt; y &lt;a href="http://www.norvig.com/"&gt;Peter Norvig&lt;/a&gt;. Ver el sitio del libro&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima.cs.berkeley.edu/"&gt;http://aima.cs.berkeley.edu/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hay implementaciones en distintos lenguajes:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima.cs.berkeley.edu/code.html"&gt;http://aima.cs.berkeley.edu/code.html&lt;/a&gt; (hay en Python, Java, C#, Prolog, Lisp, … )&lt;/p&gt;  &lt;p&gt;Mi implementación en&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SharpAima"&gt;https://github.com/ajlopez/SharpAima&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Quiero ir armándola con TDD. Por ahora me baso en la versión en Python, pero puede que también vea la versión en Java, debido a las diferencias de los lenguajes: C# y Java son lenguajes tipados.&lt;/p&gt;  &lt;p&gt;La versión que presento hoy es la 0.0.1&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/SharpAima/tree/0.0.1"&gt;https://github.com/ajlopez/SharpAima/tree/0.0.1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Por cada post iré “taggeando” una nueva versión. Mi primer código trata de implementar los primeros agentes descriptos en el capítulo 2. Me basé en el código de:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://aima-python.googlecode.com/svn/trunk/agents.py"&gt;http://aima-python.googlecode.com/svn/trunk/agents.py&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tengo una solución con dos proyectos: uno de clases y otro de tests:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/sharpaima0101.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;La idea es tener agentes en un ambiente:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/sharpaima0102.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;(Adaptado de la figura 2.1 del libro)&lt;/p&gt;  &lt;p&gt;El agente recibe percepciones y genera acciones. La primera implementación es:&lt;/p&gt;  &lt;pre style="background-color:black;color:white;"&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;abstract&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; Agent&lt;span style="color:cyan;"&gt;&amp;lt;&lt;/span&gt;TLocation&lt;span style="color:cyan;"&gt;,&lt;/span&gt; TPerception&lt;span style="color:cyan;"&gt;,&lt;/span&gt; TAction&lt;span style="color:cyan;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;public&lt;/span&gt; TLocation Location &lt;span style="color:cyan;"&gt;{&lt;/span&gt; get&lt;span style="color:cyan;"&gt;;&lt;/span&gt; set&lt;span style="color:cyan;"&gt;;&lt;/span&gt; &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;int&lt;/span&gt; Performance &lt;span style="color:cyan;"&gt;{&lt;/span&gt; get&lt;span style="color:cyan;"&gt;;&lt;/span&gt; set&lt;span style="color:cyan;"&gt;;&lt;/span&gt; &lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;abstract&lt;/span&gt; TAction GetAction&lt;span style="color:cyan;"&gt;(&lt;/span&gt;TPerception perception&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Y las implementaciones en concreto son de un agente robot máquina aspiradora (VacuumAgent y variantes).&lt;/p&gt;

&lt;p&gt;Vean la historia del proyecto, cómo fue evolucionando desde TDD. Primero implementé un agente concreto, y luego fue surgiendo la abstracción de arriba. Noten que en C# tenemos que apelar a algo tipado, y de ahí el uso de tipos genéricos: un tipo de agente concreto se define dando el tipo de lugares (location) que maneja (por ejemplo, una posición X, Y, a implementar en la próxima versión), el tipo de percepciones que recibe (ej: “estoy en lugar A y el lugar está limpio”), y el tipo de acciones (“Limpiar”, “Ir a la Derecha”, … ). En Python es más simple, por no tener tipos.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827934" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Proyectos+de+C_26002300_243_3B00_digo+Abierto/default.aspx">Proyectos de C&amp;#243;digo Abierto</category></item><item><title>AjGa: una librería de algoritmos genéticos</title><link>http://msmvps.com/blogs/lopez/archive/2009/01/28/ajga-una-librer-237-a-de-algoritmos-gen-233-ticos.aspx</link><pubDate>Wed, 28 Jan 2009 07:33:03 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1666502</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1666502</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2009/01/28/ajga-una-librer-237-a-de-algoritmos-gen-233-ticos.aspx#comments</comments><description>&lt;p&gt;Estuve codificando una librería de algoritmos genéticos, usando C#. El código está en mi proyecto &lt;a href="http://code.google.com/p/ajcodekatas/" target="_blank"&gt;AjCodeKatas en Google Code&lt;/a&gt;&amp;nbsp;dentro de:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjGa&lt;/a&gt;&lt;/p&gt; &lt;p&gt;El proyecto principal es AjGa (con AjGa.Tests para testing):&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgasln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Las principales interfaces son:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgaint.png" alt="" /&gt;&lt;/p&gt; &lt;p&gt;Uso generics, con dos tipos genéricos: G, que es el tipo de implementación de un gen, y V como el tipo al que se evalúa un genoma (por ejemplo, int, double). Con ese valor se catalogan los genomas.&lt;/p&gt; &lt;p&gt;IPopulation es una colección de genomas.&lt;/p&gt; &lt;p&gt;IGenome &amp;nbsp;es una colección&amp;nbsp;de genes, que&amp;nbsp;es evaluado a un valor de tipo V.&lt;/p&gt; &lt;p&gt;IEvaluator está a cargo de evaluar un genoma.&lt;/p&gt; &lt;p&gt;La implementación de IEvolution ejecuta generaciones sobre una población, que va cambiando, usando mutadores, operadores de cruzamiento, para irla modificando después de cada ejecución.&lt;/p&gt; &lt;p&gt;Hay interfaces para generar un genoma, mutar uno existente o hacer cruzamiento de dos genomas.&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgacd.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Para probar estas ideas, implementé un proyecto con gen, genoma, y operadores, que ataca el clásico problema del Travelling Salesman Problem, el vendedor que tiene que visitar una serie de ciudades, minimazando la distancia a recorrrer:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatspprj.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;En este ejemplo, el evaluador tiene una lista de posiciones de ciudades a visitar:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:d2ccf8d5-26f7-4c4f-9980-20d15c5489ec" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Evaluator : IEvaluator&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Position&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions;

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Evaluator(List&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;Position&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;&lt;span style="color:#000000;"&gt;.positions &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; positions;
        }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El tipo de gen acá es int, y cada valor de genoma se expresa como un int. El genoma mantiene una lista de enteros, que representan el&amp;nbsp;número ordinal de las ciudades a visitar:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:2ba01ca7-37cc-404b-9b73-a7bb089f9ef0" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjGa;

    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Genome : BaseGenome&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {        
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Genome(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; size)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; k &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#000000;"&gt;0&lt;/span&gt;&lt;span style="color:#000000;"&gt;; k &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; size; k&lt;/span&gt;&lt;span style="color:#000000;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
            {
                AddGene(k);
            }
        }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Esto es, cada gen es un int, y un genoma con genes 2, 0, 1, representa un viaje que visita la tercera ciudad, pasa por la primera, y termina en la segunda.&lt;/p&gt;
&lt;p&gt;Podemos ejecutar el proyecto WinForm, para probar esta implementación:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatsp1.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En la ejecución de arriba, la distribución de ciudades es al azar. Las ciudades pueden ser distribuidas en una grilla:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatsp2.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;De esta forma, podemos probar la eficiencia del algoritmo para encontrar un solución óptima, que en el caso de disponer las ciudades en grilla, se conoce de antemano.&lt;/p&gt;
&lt;p&gt;Si queremos implementar un nuevo proyecto GA, tenemos que:&lt;/p&gt;
&lt;p&gt;- Definir el tipo que tendrán los genes&lt;/p&gt;
&lt;p&gt;- Definir el tipo valor a usar&lt;/p&gt;
&lt;p&gt;- Escribir operadores (creadores, mutadores, cruzadores) de genomas&lt;/p&gt;
&lt;p&gt;Los tests que tengo están en verde:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgatests.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Buen Code coverage:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/ajgacc.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En 4 horas tuve la primera versión, gasté 3 horas explorando TSP, y cerca de 8 horas preparando y &amp;quot;tuneando&amp;quot; la aplicación WinForm.&lt;/p&gt;
&lt;p&gt;Como de costumbre, ¡me divertí escribiendo este ejemplo!&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1666502" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>Jugando con programas evolutivos</title><link>http://msmvps.com/blogs/lopez/archive/2008/12/16/jugando-con-programas-evolutivos.aspx</link><pubDate>Tue, 16 Dec 2008 08:59:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1656840</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1656840</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/12/16/jugando-con-programas-evolutivos.aspx#comments</comments><description>&lt;p&gt;El fin de semanas, estuve escribiendo un ejercicio casi tipo &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html" target="_blank"&gt;codekata&lt;/a&gt;. Me gusta explorar la idea de programas evolutivos (como agentes con programas incorporados que van evolucionando en ambientes simulados), así que puse manos a la obra, y creé una solución dedicada a experimentar con una ejemplo de prueba de concepto. Está escrito en C#, usando VS 2008, usando el soporte de test de la herramienta. He publicado el código dentro de mi Google code project &lt;a href="http://code.google.com/p/ajcodekatas"&gt;ajcodekatas&lt;/a&gt; en:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample" href="http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample"&gt;http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/EvolveExample&lt;/a&gt;&lt;/p&gt; &lt;p&gt;La solución es &lt;strong&gt;EvolveExample&lt;/strong&gt;:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplesln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;(Si no tienen el soporte de test de VS, pueden remover el proyecto &lt;strong&gt;Evolve.Test&lt;/strong&gt;).&lt;/p&gt; &lt;p&gt;Las clases principales residen en el proyecto de librería de clases &lt;strong&gt;Evolve&lt;/strong&gt; :&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplecld.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Animal&lt;/strong&gt; representa&amp;nbsp;un agente. Tiene una lista de&amp;nbsp;Instructions, que son generadas al azar. El animal habita un campo con&amp;nbsp;comida.&amp;nbsp;Su programa tiene instrucciones como Eat, Move East, North, West, South, o Predate (tomar energía/comida de otro animal que esté en la misma celda de la grilla). Cada instrucción tiene un costo: un punto de energía. Eat es una instrucción que toma 10 puntos de energía o menos, tomando comida de la celda actual. Predate toma 100 puntos de energía o menos, restándoselo a otro animal que esté en la misma celda.&lt;/p&gt; &lt;p&gt;Para ver el programa en acción, lanzar el proyecto winform &lt;strong&gt;Evolve.GUI&lt;/strong&gt;, seleccionar la opción &lt;strong&gt;Evolve -&amp;gt; Run&lt;/strong&gt;. Veremos:&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.todocontenidos.com/images/articles/evolveexamplegui.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;El campo es una grilla (en este ejemplo, de 20x20). Cada celda tiene un nivel de comida (verde está llena, negro es vacía). A la derecha, una lista muestra los mejores animales y sus programas. Los animales son rankeados de acuerdo a su nivel de energía al final de cada ronda de simulación. El programa continúa con más simulaciones, usando nuevos campos. En cada nueva simulación, la población es ordenada por energía descendente, y los mejores son incluidos en la nueva simulación,&amp;nbsp;los lugares vacantes son ocupados por mutaciones de esos mejores, y algunos&amp;nbsp;animales son inyectados con programas aleatorios.&lt;/p&gt; &lt;p&gt;Durante una simulación, aparece información sobre el nivel de comida y el animal que mejor se desempaña, al pie de la ventana.&lt;/p&gt; &lt;p&gt;Con las opciones de menú &lt;strong&gt;Food&lt;/strong&gt; y &lt;strong&gt;Population&lt;/strong&gt; podemos establecer el nivel de comida y el número de animales, a usar al comienzo de cada simulación. Estos valores se usan recién la próxima vez que elijamos &lt;strong&gt;Evolve -&amp;gt; Run&lt;/strong&gt;. La opción &lt;strong&gt;Evolve -&amp;gt; Stop&amp;nbsp;&lt;/strong&gt;puede ser usado para terminar una serie de simulaciones.&lt;/p&gt; &lt;h3&gt;Próximos pasos&lt;/h3&gt; &lt;p&gt;Este es un primer ejemplo, una prueba de concepto que sirva de base. Tengo algunas ideas, para explorar en futuras versiones:&lt;/p&gt; &lt;p&gt;- Tener un conjunto de instrucciones más interesantes, con condicionales, y que sea sensible al ambiente. Me gustaría añadir instrucciones como &amp;quot;Si hay comida en tal dirección, ir hacia allí&amp;quot;. En vez de un programa lineal, podría armar un árbol de instrucciones, algo como un programa Lisp.&lt;/p&gt; &lt;p&gt;- Los valores de ejecución (tamaño del campo, nivel de comida, energía inicial para cada animal), deberían poder establecerse por un formulario, y leer y grabarse de archivos XML.&lt;/p&gt; &lt;p&gt;- Serializar los resultados y poblaciones en archivos XML&lt;/p&gt; &lt;p&gt;- Evolución en un cluster. Podría usar AjMessages, AjAgents, o MPI sobre unc luster HPC, para simular evolución en una grilla o cluster de máquinas.&lt;/p&gt; &lt;p&gt;Como es habitual, ¡me divertí escribiendo este código!&lt;/p&gt; &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;br /&gt;&lt;a href="http://delicious.com/ajlopez"&gt;http://delicious.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1656840" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category></item><item><title>AjLisp: un intérprete Lisp en .NET</title><link>http://msmvps.com/blogs/lopez/archive/2008/07/31/ajlisp-un-int-233-rprete-lisp-en-net.aspx</link><pubDate>Thu, 31 Jul 2008 13:30:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1642818</guid><dc:creator>lopez</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1642818</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2008/07/31/ajlisp-un-int-233-rprete-lisp-en-net.aspx#comments</comments><description>&lt;p&gt;Soy un entusiasta de escribir intérpretes, especialmente del tipo Lisp. Mi primer intérprete Lisp fue escrito al principio de los 80, usando el lenguaje assembler de un Intel 808x. Era un trabajo muy &amp;quot;geek&amp;quot;. Una de las características más &amp;quot;tricky&amp;quot; de implementar es un recolector de basura (garbage collector). Por suerte, desde mediados de los 90 tenemos Java y su&amp;nbsp; librería de clases como una tecnología ampliamente disponible con un garbage collector decente. En este siglo, .NET es la nueva plataforma de lenguajes con GC..&lt;/p&gt; &lt;p&gt;En el&amp;nbsp;2005, &lt;a href="http://blog.salias.com.ar/" target="_blank"&gt;Martin Salias&lt;/a&gt;&amp;nbsp;y yo dimos un TechNight,&amp;nbsp;aquí en Buenos Aires, Argentina, para la oficina local de Microsoft. Trató sobre lenguajes implementados en .NET.&amp;nbsp;Fue&amp;nbsp;la primera vez que presenté F#, así como&amp;nbsp;P# y otros.&amp;nbsp;Despues de esa charla, la misma noche viajé a Mar del Plata, para dar otra charla sobre ASP.NET. Mar del&amp;nbsp;Plata es una bella ciudad, en frente del océano Atlántico,&amp;nbsp;a la que trato de volver cada año. Entonces, era mi primer visita luego de treinta años. En el viaje,&amp;nbsp;&amp;quot;nació&amp;quot; AjLisp.&lt;/p&gt; &lt;p&gt;Esa versión era un intérprete Lisp escrito en Visual Basic .NET. El pasado domingo, lo porté a C# (usando alguna opción de menú de SharpDevelop, ¿alguna otra herramienta que conozcan?). El código original fue usado hace unas semanas en mi post sobre&amp;nbsp;VPL:&lt;/p&gt; &lt;p&gt;&lt;a title="Lisp-like interpreter using DSS and VPL" href="http://ajlopez.wordpress.com/2008/06/09/lisp-like-interpreter-using-dss-and-vpl/"&gt;Lisp-like interpreter using DSS and VPL&lt;/a&gt;&lt;br /&gt;&lt;a title="Int&amp;eacute;rprete tipo Lisp usando DSS y VPL" href="http://msmvps.com/blogs/lopez/archive/2008/06/11/int-233-rprete-tipo-lisp-usando-dss-y-vpl.aspx"&gt;Intérprete tipo Lisp usando DSS y VPL&lt;/a&gt;&lt;/p&gt; &lt;p&gt;La nueva versión C# version está publicada en Google Code en:&lt;/p&gt; &lt;p&gt;&lt;a title="http://code.google.com/p/ajlisp/" href="http://code.google.com/p/ajlisp/"&gt;http://code.google.com/p/ajlisp/&lt;/a&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajlispgoogle.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;Me gusta&amp;nbsp;Google Code: tiene soporte de SVN, asi que uso mi cliente local TortoiseSVN para enviar los cambios en el proyecto.&lt;/p&gt; &lt;h3&gt;La solución&lt;/h3&gt; &lt;p&gt;Tiene tres proyectos:&lt;/p&gt; &lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajlispsln.png" alt="" /&gt; &lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjLisp&lt;/strong&gt;: el proyecto núcleo, una librería, que puede ser invocada desde otra aplicación.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjLisp.Tests&lt;/strong&gt;: Todos los tests, usando NUnit 2.2.8. Si no tienen NUnit, pueden remover el proyecto de la solución.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;AjLisp.Console&lt;/strong&gt;: un simple programa de consola.&lt;/p&gt; &lt;h3&gt;Los tipos&lt;/h3&gt; &lt;p&gt;Una interfaz base es &lt;strong&gt;IAtom&lt;/strong&gt;:&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1fdf33bc-cbd8-428f-a086-0a973fd0b495" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IAtom
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; IsAtom();
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Otra es &lt;strong&gt;IList&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:af4e475d-5592-440e-8e6e-cb47ae443def" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;interface&lt;/span&gt;&lt;span style="color:#000000;"&gt; IList
    {
        SymbolicExpression First
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }

        SymbolicExpression Rest
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;get&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; IsList();
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Todos los tipos derivan de una SymbolicExpression:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:8b612956-e1db-4f06-8e0b-1641a003b53f" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#0000FF;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; AjLisp.Types
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression : IList, IAtom
    {
 ....
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Implementé los tipos comunes a usar en un&amp;nbsp;Lisp, como List, Atom, Identifier, Function (para invocar a primitivas y funciones generadas por lambdas), True, Nil...:&lt;/p&gt;
&lt;p&gt;Existe una clase Environment para mantener valores asociados a nombres. Cada Environment tiene un Environment padre, para mantener una lista de ambientes con valores.&lt;/p&gt;
&lt;p&gt;La clase Interpreter es la principal a manejar: tiene un Environment y define algunos nombres para las primitivas iniciales:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:3f5d7f67-0306-4998-a6cc-d503bea9ba10" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;padding-top:0px;"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Interpreter
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; Environment environment &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; Environment();

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; Interpreter()
        {
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;nil&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, Nil.Value);
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;t&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, True.Value);
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;cons&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrCons());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;first&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrFirst());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;car&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrFirst());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;rest&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrRest());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;cdr&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrRest());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;list&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrList());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;quote&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrQuote());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;append&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrAppend());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;cond&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrCond());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;atom&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrAtom());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;eval&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrEval());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;null&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrNull());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;lambda&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrLambda());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;progn&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrProgN());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;flambda&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrFLambda());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;nlambda&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrNLambda());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;mlambda&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrMLambda());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;numberp&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrNumberP());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;functionp&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrFunctionP());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;idp&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrIdP());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;define&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrDefine());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;definef&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrDefineF());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;definen&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrDefineN());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;definem&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrDefineM());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;eq&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrEq());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrIf());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;let&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrLet());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;lets&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrLetS());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;set&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrSet());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;consp&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrConsP());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;less&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrLess());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;greater&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrGreater());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;plus&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrPlus());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;difference&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrDifference());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrTimes());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;quotient&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrQuotient());
            Define(&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;remainder&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrRemainder());
        }

....&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Uds. pueden escribir sus propias primitivas y agregarlas a este constructor.&lt;/p&gt;
&lt;h3&gt;Las primitivas&lt;/h3&gt;
&lt;p&gt;El intérprete tiene las primitivas usuales:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajlispprim.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Hay primitivas, que antes de su invocación, evalúan los argumentos recibidos. Son las que derivan de &lt;strong&gt;Subr&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:837dc062-a1ab-414c-8512-5dcd05e044df" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;width:551px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; Subr : Function
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression Execute(SymbolicExpression args, Environment env);

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression Apply(SymbolicExpression form, Environment env)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; Execute(form.Rest.Evaluate(env), env);
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;form.First es la función, y&amp;nbsp;form.Rest es la lista de argumentos. Para evaluar el form, Function usa un objeto Environment. &lt;/p&gt;
&lt;p&gt;Otras primitivas no evalúan sus argumentos, derivan de &lt;strong&gt;FSubr&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e90ae27a-5861-4b80-8123-f7afef71c8f1" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;width:526px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubr : Function
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;abstract&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression Execute(SymbolicExpression args, Environment env);

        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression Apply(SymbolicExpression form, Environment env)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; Execute(form.Rest, env);
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Una de las primitivas más interesantes, es la implementación de lambda, llamada FSubrLambda:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:71b9c875-831e-4eb0-aea8-5035f7fe4cf9" style="padding-right:0px;display:inline;padding-left:0px;float:none;padding-bottom:0px;margin:0px;width:599px;padding-top:0px;"&gt;&lt;pre style="background-color:White;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;"&gt;&lt;div&gt;&lt;span style="color:#000000;"&gt;    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; FSubrLambda : FSubr
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;override&lt;/span&gt;&lt;span style="color:#000000;"&gt; SymbolicExpression Execute(SymbolicExpression args, Environment env)
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; SubrClosure(args.First, env, args.Rest);
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Crea un Closure, una manera de recordar el Environment actual para usarlo en una futura invocación de la expresión lambda. Implementé también NLambda, FLambda, MLambda: N es por NonSpread (maneja su lista de argumentos como si fuera un solo argumento), F es cuando no son evaluados los argumentos antes de la invocación, y M es por Macro (tengo que revisar hasta donde implementé esta &amp;quot;feature&amp;quot;).&lt;/p&gt;
&lt;h3&gt;Los tests&lt;/h3&gt;
&lt;p&gt;Toda la funcionaliad está cubierta por tests. Configuré el proyecto AjLisp.Test para ejecuter NUnit GUI:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajlisptests.png" alt="" /&gt; &lt;/p&gt;
&lt;h3&gt;La consola&lt;/h3&gt;
&lt;p&gt;AjLisp.Console es un simple programa de consola. Pueden ingresar una expresión y la evalúa:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="http://www.ajlopez.com/images/articles/ajlispconsole.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Es tan simple, que hay que usar Control-C para salir... ;-).&lt;/p&gt;
&lt;h3&gt;Próximos pasos&lt;/h3&gt;
&lt;p&gt;Hay tanto para hacer. Quiero mejorar algunos puntos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reescribir interfaces y clases de base 
&lt;li&gt;Manejar e invocar objetos .NET nativos 
&lt;li&gt;Tratar a Reales y Enteros por separado (hoy a ambos, al operar, los trata como valores double) 
&lt;li&gt;Revisar Macro expansion
&lt;li&gt;Mejor consola 
&lt;li&gt;Librería de ejemplos 
&lt;li&gt;Un manual mínimo&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;La idea es llegar a extender este mini lenguaje para ser usado como la base programación de agentes distribuidos. Sería bueno portarlo a Java. Entonces, la conducta de los agentes y su estado puede ser escrito en este lenguaje, y viajar a distintos nodos de la grilla, de forma independiente a la plataforma.&lt;/p&gt;
&lt;p&gt;Bueno, son sueños. Ahora, el estado actual: está funcionando, y me divertí escribiéndolo. Disfruten!&lt;/p&gt;
&lt;p&gt;(Este artículo es una traducción a Spanish, desde el Anglish (Angel&amp;#39;s English) original:&lt;br /&gt;&lt;a title="AjLisp- a Lisp interpreter in .NET" href="http://ajlopez.wordpress.com/2008/07/30/ajlisp-a-lisp-interpreter-in-net/"&gt;AjLisp- a Lisp interpreter in .NET&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;)&lt;/p&gt;
&lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez&lt;br /&gt;&lt;a href="http://www.ajlopez.com/en"&gt;http://www.ajlopez.com/en&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1642818" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inteligencia+Artificial/default.aspx">Inteligencia Artificial</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/AjLisp/default.aspx">AjLisp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category></item></channel></rss>