Autor Tema: SISTEMAS EXPERTOS: Programación en NOTACION POLACA (CLIPS) E INVERSA (RPNL)  (Leído 9404 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
En la mayoría de programas de ingeniería electronica, hay un curso o electiva la cual es INTELIGENCIA ARTIFICIAL, abarca varias ramas como VISION ARTIFICIAL, ROBOTICA, HABLA-LENGUAJE, SISTEMAS NEURONALES, entre otras ramas como SISTEMAS EXPERTOS y la cual me enfocare en este nuevo hilo, pero desde el punto de vista de la programación informática.

El titulo menciona LISP un lenguaje de procedimientos secuenciales, como los lenguajes convencionales JAVA, C, C++ pero difiere en que LISP no usa la programación imperativa sino el paradigma funcional o tipo de procedimientos por funciones, además puede realizar procesamiento paralelo de datos en listas de ahi su nombre "LISt Processing" (Proceso de LIStas). usando los paréntesis ( ) como contenedores de datos, otros lenguajes usan las llaves { } para representar listas, la sintaxis de LISP es NOTACIÓN POLACA y las listas  con paréntesis hacen que este lenguaje sea a simple vista difícil de abstraer

LISP fué un lenguaje utilizado en Inteligencia Artificial (IA) pero puede ser interesante aprender LISP ya que las ultimas versiones del lenguaje C++ incluye el paradigma de programacion funcional, distribución conocida como C++11. También puede ser interesante aprender LISP por que la nasa en 1984 creo un lenguaje basado en la sintaxis de LISP, se llama muy similarmente como CLIPS (C Language Integrated Production System) https://es.wikipedia.org/wiki/CLIPS, pero CLIPS es un lenguaje multiparadigma o hibrido procedimental en cierta parte, es declarativo y basado en reglas, comparte con LISP la sintaxis o notación POLACA

El titulo menciona también RPNL, un lenguaje similar a LISP, pero el RPNL es mas moderno y mejor sintaxis, los contenedores de listas son llaves { } , usa bloques de estructuras IF THEN END; FOR NEXT, DO WHILE, etc, el RPNL esta disponible en varias calculadoras e incluso en la ultima calculadora de Hewlett Packard, la HPPrime, con LISP comparte la filosofía del procesamiento paralelo de datos por medio de listas, además de sintaxis o notación POLACA

LENGUAJE RPNL

Conozco muy bien el RPNL, y esto gracias a que compre una calculadora HP48GX programable en RPNL. En la universidad cada curso como álgebra, álgebra lineal, calculo vectorial, y muchos otros etc, lo quería programar, codificaba cientos de rutinas en RPNL, con el RPNL fue donde aprendí la lógica de programación informática.

SISTEMA EXPERTO: es un sistema computacional que emula la habilidad de tomar decisiones como lo hace un especialista o experto humano en una rama especifica como biología, medicina, algebra, diseño, etc los sistemas expertos se usan hoy en día en ingeniería, manufactura, ciencia y otros campos del saber

un sistema experto que me interesa son los CAS (Computer Algebra System) se desarrollan en lenguaje C, JAVA, pero hay algunos que se desarrollaron en LISP, como MAXIMA, REDUCE

Todo converge en la NOTACION POLACA, de ahi el interés PRINCIPAL DE ESTA publicación, DAR A CONOCER, QUE ES Y COMO FUNCIONA LA NOTACION POLACA realizar un tutorial de RPL y depronto de LISP y CLIPS

La NOTACIÓN POLACA (NP), es algo extraña,  pero después de comprender como funciona, programar en esta lógica se vuelve muy interesante Y ADICTIVO

TIPOS DE NOTACION EN PROGRAMACION

Existen al menos 3 tipos de notación para codificar un algoritmo y paradigmas o formas de programar

Por medio de notación natural que es similar a un lenguaje formal o idioma, por ejemplo

Si valor > 5 Entonces resultado=3+4... SiNo ...

las expresiones aritméticas y algebraicas se muestras como aparecen en los libros, este tipo de notación se llama NOTACION INFIJA o también conocida como ALGEBRAICA como 3+4, es la que nos enseñan en la escuela

A: NOTACION INFIJA es en la cual se escriben los operadores como (/, *, +, -) entre los operandos, es decir los operadores están en la mayoría de veces en medio de la expresión

ejemplo 1

x=3
y=4
z = x+y // Se evalúa a z = 3+4, z finalmente contiene el numero 7

El lado derecho de la expresión « z = x+y » es « x+y » los operandos son las variables 'x', 'y' & el operador es la (suma) '+' 

En el lado izquierdo de la expresión « z = x+y » en base al operador '=' (asignación) los operandos son 'z' &  'x+y'
 
ejemplo 2

z = -x+y // Se evalúa a z = -3+4, z finalmente contiene el numero 1

Ahora el lado derecho es « -x+y »,  los operandos son también las variables 'x', 'y' & el operador es la (suma) '+', pero la variable x contiene un nuevo operador el "operador inverso aditivo" '-' que no es la resta o diferencia convirtiendose '-x' como una nueva expresión o subexpresion , en este caso en particular el operador inverso aditivo actúa como prefijo y no infijo, por eso se dijo que los operadores están en la mayoría de veces en medio de la expresión, en este caso el operado esta al inicio de la expresión.

hasta aquí, creo que todo queda claro, alguna duda me comentan
mas info de NOTACION INFIJA en https://es.wikipedia.org/wiki/Notaci%C3%B3n_de_infijo

ahora viene un meollo (lo más importante de la publicación)

B: NOTACIÓN POLACA INVERSA o también llamada notación 100% postfija también conocida como notación postfija

pensemos cuando nos enseñan a sumar o multiplicar

3
4  +
¯
7

EL PROCEDIMIENTO MANUAL, O PASO A PASO ES

colocamos en cada linea, operandos
3
luego
4
luego el operador
+
hacemos una rayita o subguion y calculamos
7

el anterior ejemplo escrito en una sola linea es 3 4 + igual a 7
se lee 3 y 4 sumar resultado 7

esto es NOTACIÓN POLACA INVERSA, ¿sorprendido?


La NOTACIÓN POLACA INVERSA (en inglés, Reverse Polish Notation, de ahí sus siglas RPN) es en la cual se escriben los operadores como (/, *, +, -, etc) al final de la secuencia, implica que los operandos están previamente escritos en una  pila (stack en inglés)

pila 3: 3
pila 2: 4
pila 1: +

al evaluarse se observa
pila 1: 7

por esta razón las calculadoras como HP48, HP50 su pantalla principal muestra una pila de datos en blanco
...
5:
4:
3:
2:
1:
:

un vídeo del funcionamiento del RPN en la calculadora HP50, aunque esta también se programa y se opera en notación estándar o algebraica


con base al RPN se creo un lenguaje el RPNL mejor conocido RPL

C: La NOTACIÓN POLACA (en inglés Polish Notation, de ahí sus siglas PN) es en la cual se escriben los operadores como (/, *, +, -, etc) al INCIO de la secuencia, implica que los operandos se listan después del operador

en RPN « 3 4 + » igual a 7,
en NP « + 3 4 », igual a 7
en notación normal o algebraica « 3 + 4 », igual a 7

Que notación prefieren ¿RPN o NP?

-------------------------------------------

Documentación sobre NP y lenguaje LISP
http://www.nachocabanes.com/tutors/manual_de_referencia_rapida_de_lisp_by_rolando_rurgos.zip
Manual de Referencia Rápida de Lisp en español


¿ha SIDO DE SU INTERÉS esta publicación?
« Última modificación: 04 de Febrero de 2016, 14:23:23 por CompSystems »
Desde Colombia

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tutorial: Programación en notación POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #1 en: 28 de Enero de 2016, 18:34:27 »
Citar
¿ha SIDO DE SU INTERÉS esta publicacion?

No se si decirte que fue de interes.. ya que no le encuentro la aplicacion, por supuesto vi y tengo ejemplos de esto. Sin ir mas lejos tengo la calculadora de mi celular que funciona de la forma LISP, pero podria decirse que es una limitacion o simplemente una forma "facil" de programacion del programa mismo.

Lo que si no sabia es que tenian nombres, realmente jamas le habia prestado atencion, imagino que es por que nunca tuve en mi poder una calculadora de ese estilo ( mas que nada por el costo )

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en notación POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #2 en: 28 de Enero de 2016, 19:15:08 »
Aplicacion:

1: Se usa la Notación Polaca (PN) y mas la Notación Polaca Inversa (RPN), para convertir expresiones algebraicas o aritméticas estándares a (PN/RPN), con el propósito de facilitar la compilación e interpretación de cualquier lenguaje de programacion, ya que un analizador sintáctico (o parser en ingles) en (PN/RPN) es mil veces superior con respecto al tiempo) que un parser en lenguaje estándar.

un buen libro que habla sobre PN (LISP) "Structure and Interpretation of Computer Programs"
Dicen todo programador serio debería leerlo alguna vez en su vida
https://github.com/sarabander/sicp-pdf/raw/master/sicp.pdf
fuente https://github.com/sarabander/sicp

2: A los que nos interesa las matemáticas (y las matemáticas sirven para modelar el mundo)  y una rama en especial el álgebra simbólica, los lenguajes en notación POLACA (en honor a un matemático loco Polaco quien lo invento) hicieron posible crear aplicaciones o software que manipula expresiones simbólicas, pues en un principio solo se podía crear algoritmos con procesos numéricos.

3: se aplica en inteligencia artificial, investigando ...


Un compañero argentino esta creando en en C++11 un interprete de LISP, noten lo interesante que es codificar en programación funcional C++11
link https://www.dropbox.com/s/1dyken80fz2a97p/lisp.cpp?dl=0
Código: C++
  1. /*
  2. * Zaskar's Mini-LISP
  3. * Small incomplete and inefficient LISP interpreter.
  4. * By Pablo Novara, zaskar_84@yahoo.com.ar,
  5. * distributed under GNU GPL license.
  6. */
  7.  
  8. #include <iostream>
  9. #include <map>
  10. #include <functional>
  11. #include <sstream>
  12. #include <list>
  13. #include <algorithm>
  14. #include <stack>
  15. #include <cstdlib>
  16. using namespace std;
  17.  
  18. class env_t; // ambiente, mapeo de nombres/operadores a procedimientos/valores
  19. using list_t = list<string>; // una lista
  20. using function_t = function<string(list_t,env_t&)>; // un operador o procedimiento
  21.  
  22. // ambiente... debería ser directamente un map, pero necesitaba la
  23. // forward declaration de la clase para function_t
  24. struct env_t : public map<string,function_t> { };
  25.  
  26. // func auxiliar para mostrar los runtime-errors
  27. string error(string s1, string s2="") { cout << "Error: " << s1 << s2 << endl; return ""; }
  28.  
  29. // conversiones entre string y verdadero/falso, y entre double y string
  30. bool stob(string s) { return s=="#t"; }
  31. string btos(bool b) { return b?"#t":"#f"; }
  32. string dtos(double d) { stringstream ss; ss<<d; return ss.str(); }
  33. double stod(string &s) {
  34.     if (s.empty() || ((s[0]<'0'||s[0]>'9') && s[0]!='.' && s[0]!='-')) {
  35.         error("invalid numeric value ",s); return 0;
  36.     } else return std::stod(s);
  37. }
  38.  
  39. // dada una lista como string, la transforma en una lista posta (list_t)
  40. list_t split(string line) {
  41.     stringstream ss(line); // el stringstream::operator>> hará el corte por espacios
  42.     string aux; list_t args;
  43.     ss>>aux; // extraer el "(" inicial
  44.     while (ss>>aux && aux!=")") {
  45.         if (aux=="(") { // si es sub-lista, saltearla completa
  46.             string aux2; int par_level=1;
  47.             while(par_level>0 && ss>>aux2) {
  48.                 if (aux2=="(") ++par_level;
  49.                 else if (aux2==")") --par_level;
  50.                 aux+=string(" ")+aux2;
  51.             }
  52.         }
  53.         args.push_back(aux);
  54.     }
  55.     return args;
  56. }
  57.  
  58. // para saber si la expresión a evaluar es una constante... versión "heurística", no es perfecta, pero alcanza
  59. bool is_constant(string in) { return in.empty() || in[0]=='\"' || (in[0]>='0'&&in[0]<='9') || (in[0]=='.'||in[0]=='-'); }
  60.  
  61. // evalua una instruccion (lista dada como string) en el ambiente dado env
  62. string eval(string in, env_t &env) {
  63.     if (is_constant(in)) return in;
  64.     if (in[0]=='(') { // si es procedimiento, destripar y ejecutar
  65.         list_t lin = split(in);
  66.         string oper = lin.front(); // nombre del proc/operador
  67.         lin.pop_front();
  68.         auto proc = env.find(oper);
  69.         if (proc != env.end())
  70.             return (proc->second)(lin,env);
  71.         else return error("undefined procedure ",oper);
  72.     } else { // si es un solo valor...
  73.         auto var = env.find(in);
  74.         if (var != env.end()) return (var->second)(list_t(),env);
  75.         else return error("unbound variable ",in);
  76.     }
  77. }
  78.  
  79. // func auxiliar que dada una lista, evalua todos sus argumentos (reemplaza la lista)
  80. void eval_all(list_t &args, env_t env) {
  81.     for(auto &x:args) x = eval(x,env);
  82. }
  83.  
  84. // para el indentado del prompt, busca el ultimo parentesis sin cerrar
  85. int pos_par(string &s) {
  86.     stack<int> pars;
  87.     for(size_t i=0;i<s.size();i++) {
  88.         if (s[i]=='(') pars.push(i);
  89.         else if (s[i]==')') {
  90.             if (pars.empty()) { s = error("unbalanced parentesis"); return 0; }
  91.             pars.pop();
  92.         }
  93.     }
  94.     if (pars.empty()) return 0; else {
  95.         size_t i = pars.top()+1;
  96.         while (i<s.length() && s[i]==' ') ++i;
  97.         while (i<s.length() && s[i]!=' ') ++i;
  98.         while (i<s.length() && s[i]==' ') ++i;
  99.         for(size_t j = i-1; j>0; --j) if (s[j]=='\n'||s[j]=='\r') return i-j-1;
  100.         return i;
  101.     }
  102. }
  103.  
  104. // dada una cadena de entrada, la reformatea un poco para que
  105. // el parseo con el stringstream sea mas facil (separa los parentesis y
  106. // colapsa los espacios extra (esto ultimo es solo estética)
  107. string normalize(string in) {
  108.     string ret;
  109.     for(size_t i=0;i<in.size();i++) {
  110.         if (in[i]==' '|| in[i]=='\n' || in[i]=='\r') {
  111.             if (ret.size()&&ret[ret.size()-1]!=' ') ret += " ";
  112.         }
  113.         else if (in[i]=='(') ret += "( ";
  114.         else if (in[i]==')') ret += ((i&&in[i-1]!=' '))?" )":")";
  115.         else ret+=in[i];
  116.     }
  117.     return ret;
  118. }
  119.  
  120. // una variable es en realidad un procedimiento que no recibe nada y retorna un
  121. // valor constante, esta función hace esos procedimientos (la usa env["define"])
  122. function_t make_var(string retval) {
  123.     return [retval](list_t args,env_t &env) {
  124.         auto it = env.find(retval);
  125.         if (it!=env.end()) return it->second(args,env); // para "(define x (lambda ....))"
  126.         if (!args.empty()) return error(retval," is not a procedure");
  127.         else return retval;
  128.     };
  129. }
  130.  
  131. // func axiliar para env["lamba"], para generar nombre auxiliares diferentes para cada nueva lambda
  132. string new_name() {
  133.     static int lambda_num = 0;
  134.     stringstream ss;
  135.     ss<<"lambda#"<<(++lambda_num);
  136.     return ss.str();
  137. }
  138.  
  139.  
  140. int main() {
  141.      
  142.     // incializar el ambiente por defecto con los built-in operators
  143.     env_t env;
  144.     env["+"]   =[](list_t args,env_t env){ eval_all(args,env); double x = stod(args.front()); args.pop_front(); for(auto &y:args) x+=stod(y); return dtos(x); };
  145.     env["-"]   =[](list_t args,env_t env){ eval_all(args,env); double x = stod(args.front()); args.pop_front(); if (args.empty()) x=-x; for(auto &y:args) x-=stod(y); return dtos(x); };
  146.     env["*"]   =[](list_t args,env_t env){ eval_all(args,env); double x = stod(args.front()); args.pop_front(); for(auto &y:args) x*=stod(y); return dtos(x); };
  147.     env["/"]   =[](list_t args,env_t env){ eval_all(args,env); double x = stod(args.front()); args.pop_front(); for(auto &y:args) x/=stod(y); return dtos(x); };
  148.     env["="]   =[](list_t args,env_t env){ eval_all(args,env); return (stod(args.front())==stod(args.back()))?"#t":"#f"; };
  149.     env["<"]   =[](list_t args,env_t env){ eval_all(args,env); return (stod(args.front())<stod(args.back()))?"#t":"#f"; };
  150.     env[">"]   =[](list_t args,env_t env){ eval_all(args,env); return (stod(args.front())>stod(args.back()))?"#t":"#f"; };
  151.     env["and"] =[](list_t args,env_t env){ for(auto &x:args) if (!stob(eval(x,env))) return "#f"; return "#t"; };
  152.     env["or"]  =[](list_t args,env_t env){ for(auto &x:args) if (stob(eval(x,env))) return "#t"; return "#f"; };
  153.  
  154.     // estructuras de control basicas
  155.     env["if"]  =[](list_t args,env_t env){
  156.         string x = eval(args.front(),env); args.pop_front();
  157.         if (stob(x)) return eval(args.front(),env);
  158.         else         return eval(args.back(),env);
  159.     };
  160.     env["cond"]=[](list_t args,env_t env){
  161.         // el cond convierte todo en una monton de ifs anidados...
  162.         string ifs = "???";
  163.         reverse(args.begin(),args.end());
  164.         for(auto x: args) {
  165.             x.insert(1," if");
  166.             x.insert(x.size()-1,ifs+" ");
  167.             ifs = x;
  168.         }
  169.         return eval(ifs,env);
  170.     };
  171.     env["else"]=[](list_t args,env_t env){ return "#t"; }; // para simplificar el cond
  172.      
  173.     // algunas constantes
  174.     env["true"]  =[](list_t args,env_t env){ return "#t"; };
  175.     env["false"] =[](list_t args,env_t env){ return "#f"; };
  176.      
  177.     // define una variable o un procedimiento... ambas son lambdas que se
  178.     // guardan en el ambiente (mapa) env
  179.     env["define"] =[](list_t args,env_t &env){
  180.         if (args.size()<2) return error("ill formed define");
  181.         string name = args.front(); args.pop_front(); // extraer el nombre de lo que se define
  182.         string retval; // lo que retorna esta definicion para mostrarle al usuario
  183.         if (name[0]=='(') { // si es un procedimiento
  184.             list_t def_args = split(name);
  185.             string pname = def_args.front(); def_args.pop_front(); // extraer el nombre...
  186.             list_t instr = args; // ...y los argumentos formales
  187.             retval = instr.back(); instr.pop_back(); // extraer la instruccion a ejecutar (lo que queda son defs anidadas)
  188.             env[pname] = [pname,retval,instr,def_args](list_t args,env_t &env){ // generar la lambda y guardarla en el mapa
  189.                 auto env2 = env; // ambiente local de la funcion, "hereda" del de la llamada
  190.                 if (def_args.size()!=args.size()) return error("bad arguments count for ",pname);
  191.                 auto it1 = def_args.begin(); auto it2 = args.begin();
  192.                 while (it1!=def_args.end()) { // reemplazar argumentos formales con actuales
  193.                     auto it = env.find(*it2);
  194.                     if (it!=env.end()) env2[*it1] = it->second; // functions (not calls) should be passed by as function
  195.                     else env2[*it1] = make_var(eval(*it2,((*it2).substr(0,9)=="( lambda ")?env2:env));
  196.                     ++it1; ++it2;
  197.                 }
  198.                 for(auto &x:instr) eval(x,env2); // para definir procedimientos anidados en el ambiente local
  199.                 return eval(retval,env2); // ejecutar el cuerpo en este ambiente
  200.             };
  201.         } else { // si es variable (valor constante)
  202.             retval = args.front(); // extraer el valor
  203.             env[name] = make_var(eval(retval,env));  // guardar en el mapa una nueva lambda que retorna ese valor
  204.         }
  205.         return name + " := " + retval; // para mostrar en el prompt
  206.     };
  207.      
  208.     // para las lambdas propias inventa un nombre y se convierte en un define
  209.     env["lambda"] =[](list_t args,env_t &env){
  210.         if (args.size()<2) return error("ill formed lambda");
  211.         string name = new_name();
  212.         stringstream ss;
  213.         ss<<"( define ( "<<name;
  214.         args.front()[0]=' ';
  215.         for(auto &x:args) ss << x << " ";
  216.         ss << ")"; eval(ss.str(),env);
  217.         return name;
  218.     };
  219.      
  220.     // funciones matematicas
  221.     env["abs"]     =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(x<0?-x:x); };
  222.     env["sqrt"]    =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(sqrt(x)); };
  223.     env["square"]  =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(x*x); };
  224.     env["exp"]     =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(exp(x)); };
  225.     env["log"]     =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(log(x)); };
  226.     env["even?"]   =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return btos(int(x)%2==0); };
  227.     env["expt"]    =[](list_t args,env_t env){ double a = stod(eval(args.front(),env)), b = stod(eval(args.back(),env)); return dtos(pow(a,b)); };
  228.     env["reminder"]=[](list_t args,env_t env){ double a = stod(eval(args.front(),env)), b = stod(eval(args.back(),env)); return dtos(int(a)%int(b)); };
  229.      
  230.     // otras de utilería
  231.     env["newline"] =[](list_t args,env_t env){ cout << endl; return ""; };
  232.     env["display"] =[](list_t args,env_t env){ for(auto &x:args) cout << eval(x,env) << " "; cout << endl; return ""; };
  233.     env["random"]  =[](list_t args,env_t env){ double x = stod(eval(args.front(),env)); return dtos(rand()%int(x)); };
  234.      
  235.     // prompt interactivo, lee y ejecuta hasta fin de archivo (o ctrl+d)
  236.     cout << "Welcome to Zaskar's mini LISP!" << endl;
  237.     string in, aux;
  238.     while(cout << "$ " && getline(cin,in)) {
  239.         // si no termino la instruccion (faltan cerrar parentesis), indentar y continuar
  240.         while (pos_par(in)!=0 && cout << "  " << string(pos_par(in),' ') && getline(cin,aux))
  241.             in+=string("\n")+string(pos_par(in),' ')+aux;
  242.         cout << eval(normalize(in),env) << endl; // normalizar entrada, ejecutar, y mostrar resultado
  243.     }
  244.     cout << endl << "Have a nice day!" << endl;
  245. }


un video RPN, Así Comienza Todo ...

« Última modificación: 31 de Enero de 2016, 01:52:39 por CompSystems »
Desde Colombia

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #3 en: 30 de Enero de 2016, 00:50:10 »
« Última modificación: 30 de Enero de 2016, 01:15:16 por CompSystems »
Desde Colombia

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #4 en: 30 de Enero de 2016, 14:56:08 »
Mi pregunta para vos CompSystems (o el que tenga una mejor idea que yo) es ...

¿Para que usaria la notacion postfija o prefija?
Hasta ahora lo unico que veo en los videos y en el texto es una forma de complicarse la vida en hacer las operaciones. Y lo unico que veo "bueno" es que es mas simple para alguien crear un algoritmo que funcione a traves de esto y no un parser "algebraico".

A mi me gusta la matematica, algebra, etc. Pero hasta ahora solo le veo la complicacion y no la solucion, ya que estas haciendo el tutorial me gustaria si es que puedes indicarme cual es el sentido de tenerlo y que yo lo mas seguro no estoy viendolo. Tal ves para trabajar con vectores, no se.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #5 en: 30 de Enero de 2016, 15:51:15 »
Quiero mostrar unos ejemplos en RPL, LISP y sus versiones en C, o MATLAB por ejemplo para sacar conclusiones


Sobre los lenguajes basados en notación POLACA puedo decir que

A: Son muy simples de codificar, al principio parece imprácticos, y poco comprensibles
B: procesan datos paralelos, pensemos la suma y producto de cuatro números

ALGEBARICO (lenguaje normal):
resultadoSuma=2+4+6+8; // resultadoSuma -> 20
resultadoMul=2*4*6*8; // resultadoMul -> 384

RPL:
{2,4,6,8} sumar => 20
{2,4,6,8} multiplicar => 384

en RPL no hay necesidad de almacenar las sentencias en una variable, por que están en una pila o stack, de pueden bajar, o leer cualquier posición del stack para manipular la información, procesan lista de objetos  {2,4,6,8}  en incluso lista de listas, incluyendo además cadenas u otros objetos y entre listas

RPL:
{"1","2","3"} sumar => "123"
{1,2,3} {2,4,8} multiplicar => {2,8,18}

podemos aplicar procedimientos a cada elemento de una lista
{1,2,3} ! aplicar => {1,2,6}
e incluso a un vector o matrix

siguiendo esta lógica, los algoritmos se llevan a código en un menor tiempo, menor código y mayor velocidad de procesamiento

en la hp50 tiene la opción de entrar también expresiones matemáticas en modo normal, solo se debe contenerlas entre un par de comillas simples

['X', 'X^2', 'X^3'] 'X' integrar => [ 'SQ(X)/2' '1/3*X^3' '1/4*X^4' ]

se pueden convertir listas a vectores o matrices

X, X 2 ^, X 3 ^ 3LIST LISTtoMAT => ['X', 'X^2', 'X^3']

paso a paso

coloca en el stack X
luego X 2 ^ (piense en RPN) que es 'X^2'
luego X 3 ^ que es 'X^3'
luego hace una lista con los 3 niveles del stack ósea   {'X', 'X^2', 'X^3'}
luego convierte la lista a vector ['X', 'X^2', 'X^3']

creo que python trabaja algo similar

también se puede extraer elementos de una lista fácilmente

{'X', 'X^2', 'X^3'} 3 GET => 'X^3'

Colocar elementos a una lista o vector

{'X', 'X^2', 'X^3'} 2 5 PUT  => {'X', 5, 'X^3'}

así por el estilo es la magia del RPN
« Última modificación: 30 de Enero de 2016, 16:10:19 por CompSystems »
Desde Colombia

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #6 en: 30 de Enero de 2016, 22:17:34 »
Mi pregunta para vos CompSystems (o el que tenga una mejor idea que yo) es ...

¿Para que usaria la notacion postfija o prefija?
Hasta ahora lo unico que veo en los videos y en el texto es una forma de complicarse la vida en hacer las operaciones. Y lo unico que veo "bueno" es que es mas simple para alguien crear un algoritmo que funcione a traves de esto y no un parser "algebraico".

A mi me gusta la matematica, algebra, etc. Pero hasta ahora solo le veo la complicacion y no la solucion, ya que estas haciendo el tutorial me gustaria si es que puedes indicarme cual es el sentido de tenerlo y que yo lo mas seguro no estoy viendolo. Tal ves para trabajar con vectores, no se.

yo la ventaja que le veo al rpl es la gran velocidad que se obtiene para hacer cálculos
Si eso sirve o no dependerá de la opinion de cada uno. Yo desde que tengo la 48gx nunca más agarre otra calculadora y te digo que si agarro ua casio comun tengo que pensar un monton para hacer cuentas.
 En la facultad hacíamos competencias para resolver cuentas simples (pero muchas combinaciones) con fanaticos del rpl vs los tradicionales, todos con calculadoras "avanzadas"... los de rpl ganábamos siempre  :D :D

muy interesante el hilo!
-
Leonardo Garberoglio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #7 en: 31 de Enero de 2016, 00:24:10 »
Es que justamente yo nunca tuve la necesidad de realizar estos calculos, es decir tengo una Casio que me sirve para las cosas "mas simples", complejos,determinantes, etc , lo que puede traer algo comun, y luego siempre cuando necesite algo mas complejo, ejemplo trabajar con matrices pase directametne a MATLAB. Por eso es que tal ves yo no le encuentro una aplicacion al no haberlo usado. Y es lo que pedia como un ejemplo en el que claramente tengas esa ventaja, pero no un ejemplo en el sentido de .. { 3 6 9 12} 3 / y listo, como probando que se puede hacer, sino en que se lo aplicaria.

Ojo, que no se piense que estoy en contra ni nada por el estilo, solo busco informarme y aprender.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #8 en: 31 de Enero de 2016, 00:50:06 »
que bueno fuero que existiera un RPL en Matlab, Mathematica, Maxima, etc de seguro que muchos se inclinarían por el RPL

Dicen que fundamentarse en RPL, se entendería mejor la nueva característica del C++11 y Java  que es la programación funcional. Una razón más o interés de dar a conocer el RPL


Dice en Wikipedia sobre programación funcional mediante expresiones Lambda o calculo Lambda:
El cálculo lambda tiene una gran influencia sobre los lenguajes funcionales, como Lisp, aunque c++ y java no son funcionales en su origen, están incorporando este tipo de programación en sus ultimas versiones

https://es.wikipedia.org/wiki/C%C3%A1lculo_lambda

en el código mostrado arriba en C++, se muestra la programación funcional


Java SE 8 — lanzada en marzo de 2014. Cabe destacar:
Incorpora de forma completa la librería JavaFX.
Diferentes mejoras en seguridad.
Diferentes mejoras en concurrencia.
Añade funcionalidad para programación funcional mediante expresiones Lambda.
« Última modificación: 31 de Enero de 2016, 01:53:19 por CompSystems »
Desde Colombia

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #9 en: 31 de Enero de 2016, 06:36:30 »
El lenguaje Forth está basado en pila y utiliza la notación polaca inversa.
https://es.wikipedia.org/wiki/Forth

Es un lenguaje muy eficiente, potente y de fácil depuración, aunque requiere una disciplina especial para programar.
Se utilizó en el space shuttle entre otros grandes proyectos. Está pensado para aplicaciones embebidas.
http://www.forth.org/successes.html

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #10 en: 31 de Enero de 2016, 06:45:34 »
Las calculadoras HP utilizan un lenguaje basado en Forth y en Lisp.
De hecho los programas de las HP parecen Forth.

Un saludo.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #11 en: 01 de Febrero de 2016, 11:31:55 »
Picuino muy interesante sobre Forth, por favor puedes aportar algunos ejemplos aplicados, puede ser en sistemas embebidos o solo código demostrativo

Gracias
Desde Colombia

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #12 en: 01 de Febrero de 2016, 12:36:18 »
print  (25 * 10) + 50

Forth:
25 10 * 50 + .

HP48:
25 Enter 10 * +



print x*x
(x es un argumento que está en la pila)

Forth:
DUP * .

HP48:
DUP *


Hay muchos mas ejemplos en wikipedia e internet (Forth y RPL)
http://stackoverflow.com/questions/12778187/examples-of-very-concise-forth-applications

Un saludo.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #13 en: 01 de Febrero de 2016, 23:48:55 »
en un post anterior dices "aplicaciones embebidas" tu has programado un proyecto en forth, si es así lo puedes compartir
Desde Colombia

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Tutorial: Programación en NOTACION POLACA (LISP) y POLACA INVERSA (RPNL)
« Respuesta #14 en: 02 de Febrero de 2016, 09:50:54 »
No he programado proyectos en forth. Sólo en la hp48. El lenguaje y la forma de trabajo es similar.
Saludos.