2 #include "sistemaautonomo.h"
10 //--------------------------------------------------------------------------------------------
11 //-- Funciones Auxiliares
12 bool incluye_a (CIndiceMagico<t_dato>& a, CIndiceMagico<t_dato>& b)
17 // Todas las variables de la condicion b deben estar en la condicion a
18 for (i=0; i<b.count() && result; i++)
19 result=a.exist(b.keys(i)) ;
21 // Todas las variables de la condicion a deben tener el mismo valor que en la condicion b
22 for (i=0; i<b.count() && result; i++)
23 result = b[i] == a.find(b.keys(i)) || b[i] == ANY || a.find(b.keys(i)) == ANY ;
28 //--------------------------------------------------------------------------------------------
30 void CSistemaAutonomo::plan()
34 if (teorias.count() > max_teorias) purgar_teorias();
36 std::cout << "SA: Planificando...\n";
37 std::cout << "SA: \tentorno:\n" << p_entorno->datos << "\n";
38 std::cout << "SA: \tteorias:\n" << teorias << "\n";
41 std::cout << "Planificando...\n";
42 std::cout << "Entorno:\n" << p_entorno->datos << "\n";
43 std::cout << "Teorias:\n" << teorias << "\n";
45 planificar(p_entorno->datos, m_datos_finales, m_plan, p);
47 std::cout << "SA: \tplan:\n" << m_plan << "\n";
50 std::cout << "Plan:\n" << m_plan << "\n";
52 curr_theory = m_plan.begin();
54 if (curr_theory == m_plan.end())
55 std::cout << "SA: No hay teorías\n";
57 std::cout << "SA: curr teoria: " << **curr_theory << "\n";
61 //--------------------------------------------------------------------------------------------
63 bool CSistemaAutonomo::has_next_theory()
65 return curr_theory != m_plan.end();
68 //--------------------------------------------------------------------------------------------
70 CTeoria* CSistemaAutonomo::get_next_theory()
72 if (curr_theory == m_plan.end())
74 m_datos_finales.clear();
80 std::cout << "SA: ejecuta teoria: " << **(curr_theory) << "\n";
83 std::cout << "Ejecutando teoria:\n" << **(curr_theory) << "\n";
85 return *(curr_theory++);
89 //--------------------------------------------------------------------------------------------
91 bool CSistemaAutonomo::validate_theory(CTeoria* t)
95 // Aumento k (cantidad de veces que se probó la teoría
99 std::cout << "SA: Entorno de verificacion:\n" << p_entorno->datos;
103 std::cout << "Verificacion...\n";
104 std::cout << "Entorno:\n" << p_entorno->datos << "\n";
108 result = verificar_condicion(t->datos_finales) ;
110 // Si se ejecuto bien la teoria incremento el p
113 // Si fallo la teoria
116 // Aplico heuristicas de observacion
118 std::cout << "SA: No verifica, aplicando heuristicas...\n";
119 std::cout << "SA: Aplicando heuristica de observacion\n";
122 std::cout << "No verifica, aplicando heuristicas...\n";
123 std::cout << "Aplicando heuristica de observacion:\n";
125 this->heuristca_observacion(*t) ;
127 std::cout << "SA: Aplicando heuristica de generalizacion\n";
130 std::cout << "Aplicando heuristica de generalizacion:\n";
132 this->heuristca_generalizacion(*t);
134 std::cout << "SA: Aplicando heuristica de retraccion\n";
137 std::cout << "Aplicando heuristica de retraccion:\n";
139 // Aplico heuristicas de correccion
140 this->heuristca_retraccion(*t) ;
143 else std::cout << "SA: Verifica!\n";
146 else std::cout << "Verifica!\n";
153 //--------------------------------------------------------------------------------------------
155 bool CSistemaAutonomo::verificar_condicion(CIndiceMagico<t_dato>& datos)
160 for (i = 0; i < datos.count() && result; i++)
161 result = (datos[i] == ANY || datos[i] == this->p_entorno->datos.find(datos.keys(i)));
166 std::string make_nombre(const std::string& n, char mod, unsigned i)
168 std::ostringstream oss;
169 oss << n << "-" << mod << i;
173 //--------------------------------------------------------------------------------------------
175 void CSistemaAutonomo::heuristca_observacion(CTeoria& t)
177 CTeoria* pnt = new CTeoria ; //Nueva Teoria
180 // Le agrego los datos iniciales tal cual estaban antes
181 nt.datos_iniciales = t.datos_iniciales;
183 // Le agrego todas las condiciones del entorno como condicion final
184 nt.datos_finales = p_entorno->datos;
186 // Le cargo nombre y funcion (queda con k=1 y p=1)
187 nt.nombre = make_nombre(t.nombre, 'o', teorias.count());
188 nt.funcion = t.funcion;
191 teorias.add (nt.nombre, pnt) ;
193 std::cout << "SA: Se agrego una nueva teoria: " << nt << " basada en " << t << "\n";
194 std::cout << "SA: \tdatos_iniciales:\n" << nt.datos_iniciales << "\n";
195 std::cout << "SA: \tdatos_finales:\n" << nt.datos_finales << "\n";
198 std::cout << "Agrega teoria: " << nt << "," << nt.datos_iniciales << "," << nt.datos_finales << "\n";
203 //--------------------------------------------------------------------------------------------
205 // Si las condiciones finales del entorno son iguales a las condiciones finales de alguna teoria y
206 // solo una condicion inicial es distinta => agrego una nueva teoría igual (a la q cumple los requisitos
207 // anteriormente detallados) pero tomando ANY en el valor de entrada en el cual difieren.
208 void CSistemaAutonomo::heuristca_generalizacion(CTeoria& t)
214 int posicionCambio = -1;
215 unsigned cantidadTeorias = 0;
216 std::string nombreTeoria;
218 cantidadTeorias = this->teorias.count();
220 for (i = 0; i < cantidadTeorias; i++)
222 for (k = 0; k < this->teorias[i]->datos_finales.count(); k++)
224 //me fijo si las condiciones finales de la teoria se corresponden con la del entorno.
225 if ((this->teorias[i]->datos_finales[k] != ANY) && (this->p_entorno->datos.find(t.datos_finales.keys(k)) != ANY))
227 if (this->teorias[i]->datos_finales[k] != this->p_entorno->datos.find(t.datos_finales.keys(k)))
234 { // si se corresponden (las condiciones finales son iguales) => me fijo si hay alguna condicion inicial q cambia.
235 for (j = 0; j < this->teorias[i]->datos_iniciales.count(); j++)
237 if ((this->teorias[i]->datos_iniciales[j] != ANY) && (this->p_entorno->datos.find(t.datos_iniciales.keys(j)) != ANY))
239 if (this->teorias[i]->datos_iniciales[j] != this->p_entorno->datos.find(t.datos_iniciales.keys(j)))
248 //si cambia solo una => creo una nueva teoria igual pero con ANY en la condicion q cambia.
249 CTeoria* nt = new CTeoria ; //Nueva Teoria
250 *nt = *this->teorias[i];
251 nt->datos_iniciales[posicionCambio] = ANY;
254 nt->nombre = make_nombre(t.nombre, 'g', teorias.count());
255 teorias.add (nt->nombre, nt) ;
257 std::cout << "SA: Se agrego una nueva teoria: " << *nt << " basada en " << *teorias[i] << "\n";
258 std::cout << "SA: \tdatos_iniciales:\n" << nt->datos_iniciales << "\n";
259 std::cout << "SA: \tdatos_finales:\n" << nt->datos_finales << "\n";
262 std::cout << "Agrega teoria: " << *nt << "," << nt->datos_iniciales << "," << nt->datos_finales << "\n";
271 //--------------------------------------------------------------------------------------------
273 void CSistemaAutonomo::heuristca_retraccion(CTeoria& t)
276 unsigned modif = (unsigned)-1;
278 // Recorro la condicion final de la teoria
279 for (i = 0; i < t.datos_finales.count(); i++)
281 // Si el dato no coincidio con el del entorno, y no era ANY
282 if (t.datos_finales[i] != ANY &&
283 t.datos_finales[i] != this->p_entorno->datos.find(t.datos_finales.keys(i)))
286 t.datos_finales[i] = ANY ;
290 if (modif != (unsigned)-1)
292 // Le cambio el nombre para indicar que fue modificada
295 std::cout << "SA: Se modifica la teoria: " << t << ", el dato final '"
296 << t.datos_finales.keys(modif) << "' puede tomar ahora cualquier valor\n";
299 std::cout << "Se modifica teoria:\n" << t << "\nEl dato final '"
300 << t.datos_finales.keys(modif) << "' puede tomar ahora cualquier valor\n";
301 std::cout << "Agrega teoria: " << t << "," << t.datos_iniciales << "," << t.datos_finales << "\n";
307 //--------------------------------------------------------------------------------------------
309 void CSistemaAutonomo::planificar (CIndiceMagico<t_dato>& datos_iniciales,
310 CIndiceMagico<t_dato>& datos_finales,
311 CIndiceMagico<CTeoria*>& plan,
313 unsigned long numero_de_llamada)
316 CIndiceMagico<CTeoria*> test_plan ;
317 CIndiceMagico<CTeoria*> new_plan ;
322 if ( incluye_a(datos_iniciales, datos_finales) ) return ;
324 if (numero_de_llamada > max_pasos) return ;
326 for (i = 0; i < teorias.count(); i++)
327 if ( incluye_a(teorias[i]->datos_iniciales, datos_iniciales) )
330 test_plan.add (teorias[i]->nombre, teorias[i]) ;
332 test_p = p * ((double)teorias[i]->p)/((double)teorias[i]->k) ;
334 planificar(teorias[i]->datos_finales, datos_finales, test_plan, test_p, numero_de_llamada+1) ;
337 if ( incluye_a(test_plan[test_plan.count()-1]->datos_finales, datos_finales) )
341 new_plan.add (test_plan) ;
346 plan.add (new_plan) ;
349 void CSistemaAutonomo::purgar_teorias()
351 unsigned size = teorias.count();
352 unsigned pos = size - 1;
353 double whorst_prob = 1.0;
354 for (unsigned i = 0; i < size; ++i)
356 double p = (double)teorias[i]->p / (double)teorias[i]->k;
365 std::cout << "SA: Se purgo la teoria " << *teorias[pos] << "\n";
368 std::cout << "Se purgo la teoria:\n" << *teorias[pos] << "\n";
370 if (size - 1 > max_teorias) purgar_teorias();