#include "sistemaautonomo.h"
+#include <sstream>
+
+#ifdef DEBUG
+#include <iostream>
+#endif // DEBUG
//--------------------------------------------------------------------------------------------
//-- Funciones Auxiliares
+bool incluye_a (CIndiceMagico<t_dato>& a, CIndiceMagico<t_dato>& b)
+{
+ bool result = true ;
+ unsigned i ;
+
+ // Todas las variables de la condicion b deben estar en la condicion a
+ for (i=0; i<b.count() && result; i++)
+ result=a.exist(b.keys(i)) ;
+
+ // Todas las variables de la condicion a deben tener el mismo valor que en la condicion b
+ for (i=0; i<b.count() && result; i++)
+ result = b[i] == a.find(b.keys(i)) || b[i] == ANY || a.find(b.keys(i)) == ANY ;
+ //
+ return result ;
+}
+
+//--------------------------------------------------------------------------------------------
+//--
+void CSistemaAutonomo::plan()
+{
+ double p = 1.0;
+ m_plan.clear();
+#ifdef DEBUG
+ std::cout << "SA: Planificando...\n";
+ std::cout << "SA: \tentorno:\n" << p_entorno->datos << "\n";
+ std::cout << "SA: \tdatos finales:\n" << m_datos_finales << "\n";
+#endif // DEBUG
+ planificar(p_entorno->datos, m_datos_finales, m_plan, p);
+#ifdef DEBUG
+ std::cout << "SA: \tplan:\n" << m_plan << "\n";
+#endif // DEBUG
+ curr_theory = m_plan.begin();
+#ifdef DEBUG
+ if (curr_theory == m_plan.end())
+ std::cout << "SA: No hay teorías\n";
+ else
+ std::cout << "SA: curr teoria: " << **curr_theory << "\n";
+#endif // DEBUG
+}
+//--------------------------------------------------------------------------------------------
+//--
+bool CSistemaAutonomo::has_next_theory()
+{
+ return curr_theory != m_plan.end();
+}
-bool cumple_condiciones (CIndiceMagico<t_dato>& muestra, CIndiceMagico<t_dato>& patron)
+//--------------------------------------------------------------------------------------------
+//--
+CTeoria* CSistemaAutonomo::get_next_theory()
{
+ if (curr_theory == m_plan.end())
+ {
+ m_datos_finales.clear();
+ return 0;
+ }
+ else
+ {
+ return *(curr_theory++);
+ }
+}
+
+//--------------------------------------------------------------------------------------------
+//--
+bool CSistemaAutonomo::validate_theory(CTeoria* t)
+{
+ bool result ;
+
+ // Aumento k (cantidad de veces que se probó la teoría
+ ++t->k;
+ // Verifico
+ result = verificar_condicion(t->datos_finales) ;
+
+ // Si se ejecuto bien la teoria incremento el p
+ if (result) t->p++ ;
+
+ // Si fallo la teoria
+ if (!result)
+ {
+ // Aplico heuristicas de observacion
+#ifdef DEBUG
+ std::cout << "SA: No verifica, aplicando heuristicas...\n";
+ std::cout << "SA: Aplicando heuristica de observacion\n";
+#endif // DEBUG
+ this->heuristca_observacion(*t) ;
+#ifdef DEBUG
+ std::cout << "SA: Aplicando heuristica de generalizacion\n";
+#endif // DEBUG
+ this->heuristca_generalizacion(*t);
+#ifdef DEBUG
+ std::cout << "SA: Aplicando heuristica de retraccion\n";
+#endif // DEBUG
+ // Aplico heuristicas de correccion
+ this->heuristca_retraccion(*t) ;
+ }
+
+ return result;
+}
+
+
+//--------------------------------------------------------------------------------------------
+//--
+bool CSistemaAutonomo::verificar_condicion(CIndiceMagico<t_dato>& datos)
+{
bool result = true ;
unsigned i ;
- for (i=0; i<muestra.count() && result; i++)
- result = (muestra[i] == patron.find(muestra.keys(i))) ;
+ for (i = 0; i < datos.count() && result; i++)
+ result = (datos[i] == ANY || datos[i] == this->p_entorno->datos.find(datos.keys(i)));
- //
return result ;
+}
+
+std::string make_nombre(const std::string& n, char mod, unsigned i)
+{
+ std::ostringstream oss;
+ oss << n << "-" << mod << i;
+ return oss.str();
+}
+
+//--------------------------------------------------------------------------------------------
+//--
+void CSistemaAutonomo::heuristca_observacion(CTeoria& t)
+{
+ CTeoria* pnt = new CTeoria ; //Nueva Teoria
+ CTeoria& nt = *pnt;
+
+ // Le agrego los datos iniciales tal cual estaban antes
+ nt.datos_iniciales = t.datos_iniciales;
+
+ // Le agrego todas las condiciones del entorno como condicion final
+ nt.datos_finales = p_entorno->datos;
+
+ // Le cargo nombre y funcion (queda con k=1 y p=1)
+ nt.nombre = make_nombre(t.nombre, 'o', teorias.count());
+ nt.funcion = t.funcion;
+
+ // Agrego la teoria
+ teorias.add (nt.nombre, pnt) ;
+#ifdef DEBUG
+ std::cout << "SA: Se agrego una nueva teoria: " << nt << " basada en " << t << "\n";
+ std::cout << "SA: \tdatos_iniciales:\n" << nt.datos_iniciales << "\n";
+ std::cout << "SA: \tdatos_finales:\n" << nt.datos_finales << "\n";
+#endif // DEBUG
+
+}
+
+//--------------------------------------------------------------------------------------------
+//--
+// Si las condiciones finales del entorno son iguales a las condiciones finales de alguna teoria y
+// solo una condicion inicial es distinta => agrego una nueva teoría igual (a la q cumple los requisitos
+// anteriormente detallados) pero tomando ANY en el valor de entrada en el cual difieren.
+void CSistemaAutonomo::heuristca_generalizacion(CTeoria& t)
+{
+ unsigned i ;
+ int count = 0;
+ unsigned k = 0;
+ unsigned j = 0;
+ int posicionCambio = -1;
+ unsigned cantidadTeorias = 0;
+ std::string nombreTeoria;
+
+ cantidadTeorias = this->teorias.count();
+
+ for (i = 0; i < cantidadTeorias; i++)
+ {
+ for (k = 0; k < this->teorias[i]->datos_finales.count(); k++)
+ {
+ //me fijo si las condiciones finales de la teoria se corresponden con la del entorno.
+ if ((this->teorias[i]->datos_finales[k] != ANY) && (this->p_entorno->datos.find(t.datos_finales.keys(k)) != ANY))
+ {
+ if (this->teorias[i]->datos_finales[k] != this->p_entorno->datos.find(t.datos_finales.keys(k)))
+ {
+ count++;
+ }
+ }
+ }
+ if (count == 0)
+ { // si se corresponden (las condiciones finales son iguales) => me fijo si hay alguna condicion inicial q cambia.
+ for (j = 0; j < this->teorias[i]->datos_iniciales.count(); j++)
+ {
+ if ((this->teorias[i]->datos_iniciales[j] != ANY) && (this->p_entorno->datos.find(t.datos_iniciales.keys(j)) != ANY))
+ {
+ if (this->teorias[i]->datos_iniciales[j] != this->p_entorno->datos.find(t.datos_iniciales.keys(j)))
+ {
+ posicionCambio = j;
+ count++;
+ }
+ }
+ }
+ if (count == 1)
+ {
+ //si cambia solo una => creo una nueva teoria igual pero con ANY en la condicion q cambia.
+ CTeoria* nt = new CTeoria ; //Nueva Teoria
+ *nt = *this->teorias[i];
+ nt->datos_iniciales[posicionCambio] = ANY;
+
+ // Agrego la teoria
+ nt->nombre = make_nombre(t.nombre, 'g', teorias.count());
+ teorias.add (nt->nombre, nt) ;
+#ifdef DEBUG
+ std::cout << "SA: Se agrego una nueva teoria: " << *nt << " basada en " << *teorias[i] << "\n";
+ std::cout << "SA: \tdatos_iniciales:\n" << nt->datos_iniciales << "\n";
+ std::cout << "SA: \tdatos_finales:\n" << nt->datos_finales << "\n";
+#endif // DEBUG
+ }
+ }
+ posicionCambio = -1;
+ count = 0;
+ }
+}
+
+//--------------------------------------------------------------------------------------------
+//--
+void CSistemaAutonomo::heuristca_retraccion(CTeoria& t)
+{
+ unsigned i ;
+ unsigned modif = (unsigned)-1;
+ // Recorro la condicion final de la teoria
+ for (i = 0; i < t.datos_finales.count(); i++)
+ {
+ // Si el dato no coincidio con el del entorno, y no era ANY
+ if (t.datos_finales[i] != ANY &&
+ t.datos_finales[i] != this->p_entorno->datos.find(t.datos_finales.keys(i)))
+ {
+ // Le asigno ANY
+ t.datos_finales[i] = ANY ;
+ modif = i;
+ }
+ }
+ if (modif != (unsigned)-1)
+ {
+ // Le cambio el nombre para indicar que fue modificada
+ t.nombre += "-r";
+#ifdef DEBUG
+ std::cout << "SA: Se modifica la teoria: " << t << ", el dato final '"
+ << t.datos_finales.keys(modif) << "' puede tomar ahora cualquier valor\n";
+#endif // DEBUG
+ }
}
+
+//--------------------------------------------------------------------------------------------
+//--
+void CSistemaAutonomo::planificar (CIndiceMagico<t_dato>& datos_iniciales,
+ CIndiceMagico<t_dato>& datos_finales,
+ CIndiceMagico<CTeoria*>& plan,
+ double& p,
+ unsigned long numero_de_llamada)
+{
+ unsigned i;
+ CIndiceMagico<CTeoria*> test_plan ;
+ CIndiceMagico<CTeoria*> new_plan ;
+ double test_p ;
+ double max_p = 0 ;
+
+
+ if ( incluye_a(datos_iniciales, datos_finales) ) return ;
+
+ if ( numero_de_llamada > 7 ) return ;
+
+ for (i = 0; i < teorias.count(); i++)
+ if ( incluye_a(teorias[i]->datos_iniciales, datos_iniciales) )
+ {
+ test_plan.clear() ;
+ test_plan.add (teorias[i]->nombre, teorias[i]) ;
+
+ test_p = p * ((double)teorias[i]->p)/((double)teorias[i]->k) ;
+
+ planificar(teorias[i]->datos_finales, datos_finales, test_plan, test_p, numero_de_llamada+1) ;
+
+ if ( test_p>max_p )
+ if ( incluye_a(test_plan[test_plan.count()-1]->datos_finales, datos_finales) )
+ {
+ max_p = test_p ;
+ new_plan.clear() ;
+ new_plan.add (test_plan) ;
+ }
+ }
+
+ if (max_p>0)
+ plan.add (new_plan) ;
+}
+
+
+/*
+//--------------------------------------------------------------------------------------------
+//--
+bool CSistemaAutonomo::ejecutar (CIndiceMagico<CTeoria>& plan)
+{
+ bool result = true ;
+ unsigned i ;
+ t_fnc(pFnc) ;
+ CTeoria t ;
+
+
+ for (i=0; i<plan.count() && result; i++)
+ {
+ t = plan[i] ;
+ pFnc = t.funcion;
+
+ // Ejecuto la funcion
+ (*pFnc)(*(this->p_entorno)) ;
+
+ // Incremento el K
+ t.k++ ;
+
+ // Actualizo los datos del entorno
+ this->p_entorno->actualizar() ;
+
+ // Veo si se verifica la condicion final
+ result = this->verificar_condicion(t.datos_finales) ;
+
+ // Si fallo la teoria
+ if (!result)
+ {
+ // Aplico heuristicas de correccion
+ this->heuristca_retraccion(t) ;
+ }
+ else
+ {
+ t.p++ ;
+ }
+
+ // Aplico heuristicas de observacion
+ this->heuristca_observacion(t) ;
+ this->heuristca_generalizacion(t);
+ }
+
+ //
+ return result ;
+}
+*/