<html><body><pre> #!/usr/bin/perl -w # fis; encadenamiento regresivo (tipo PROLOG) en PERL # autores: Ruben Rusiles, Isela Gonzalez # DATOS # afirmaciones # [["deedee","tiene","pelo"],[["bozo","es","mamifero"],["vacio"]]] # reglas # [["identifica",["?animal","tiene","pelo"],["?animal","es","mamifero"]], # ["vacio"]] # VARIABLES GLOBALES my $afirmaciones; my $reglas; my $c = 0; # contador variables unicas # sub LISTAS Y ATOMOS ------------------------------------------------------ # -------------------------------------------------------------------------- # regresa una lista con los argumentos sub list { my $res=[]; my $valor; my $c=0; while ($valor=shift) { $res->[$c]=$valor; $c++; } return $res; } # inserta un atomo o lista dentro de una lista sub cons { my $valor=shift; my $lista=shift; my $res; for $i (0 .. $#{$lista}) { $res->[$i+1]=$lista->[$i]; } $res->[0]=$valor; return $res; } # determina la igualdad de 2 atomos y/o listas sub equal { my $list1 = shift; my $list2 = shift; if (!$list1 && !$list2) { return 1; } if (!$list1 || !$list2) { return 0; } if (atom($list1) && atom($list2)) { return eql($list1,$list2) ? 1: 0; } if (equal(car($list1),car($list2))) { return equal(cdr($list1),cdr($list2)); } return 0; } # regresa la copia de una lista sub copia { my $list = shift; my $i; my $res; if (null($list)) { $res = []; } if (!null($list)) { for $i (0..$#{$list}) { $res->[$i] = $list->[$i] ; } } return $res; } # une dos listas sub append { my $list1 = shift; my $list2 = shift; my $i; my $j; my $res; if (null($list1) && null($list2)) { $res = []; } if (!null($list1)) { for $i (0..$#{$list1}) { $res->[$i] = $list1->[$i] ; } } if (!null($list2)) { $i=$#{$list1}+1; for $j (0..$#{$list2}) { $res->[$i+$j] = $list2->[$j] ; } } return $res; } # regreso 1 si la lista es [] # regresa 0 otro caso sub null { my $valor = shift; return $#{$valor}==-1 && substr($valor,0,5) eq "ARRAY" ? 1 : 0; } # imprime una lista en forma recursiva sub v { my $valor = shift; my $res; if (! $valor) { return "0"; } if(null($valor)) { return "[]"; } if (atom($valor)) { return "\"$valor\"" ; } else { $res = "[" . v($valor->[0]) ; for $i (1 .. $#{$valor}) { $res .= "," . v($valor->[$i]); } $res .= "]"; return $res; } } #determina si un valor es lista sub listp { my $valor = shift; if (null($valor)) { return 1;} # ??? [] es lista else { return !atom($valor) ? 1 : 0;} } #determina si un valor es atomico sub atom { my $valor = shift; return ($#{$valor}==-1 && substr($valor,0,5) ne "ARRAY") || null($valor) ? 1 : 0 ; } #determina el car de una lista sub car { my $valor = shift; if (null($valor)) { return; } else { if (atom($valor)) {return;} else {return $valor -> [0];} } } #regresa el cdr de una lista sub cdr { my $valor = shift; my $res; if (atom($valor) && !null($valor)) { return; } if (length1($valor)<=1) # ??? se agrego < para [] { return []; } else { for $m (1 .. length1($valor)-1) { # ??? NO USAR cons $res->[$m-1]=$valor->[$m]; } return $res; } } # !!! length es predefinida # regresa la longitud de una lista sub length1{ my $valor=shift; if (atom($valor)==1 || null($valor)==1) { return 0; } else { return $#{$valor}+1; } } # !!! last es predefinida # devuelve el ultimo elemento de una lista sub last1 { my $lista=shift; my $n; if (null($lista)) { return; } $n = length1($lista)-1; return $lista->[$n]; } # devuelve toda la lista, menos el ultimo elemento sub butlast { my $lista = shift; my $res; for $j ( 0 .. length1($lista)-2 ) { $res->[$j]=$lista->[$j] } return $res; } sub eql{ my $at1=shift; my $at2=shift; return atom($at1) && atom($at2) && ( ($at1 eq $at2) || (null($at1) && null($at2))) ? 1 : 0; } sub member { my $list1 = shift; my $list2 = shift; if (&null($list2) || &null($list1)) { return 0; } if (&equal($list1,$list2)) { return 1; } else { if (&equal($list1,&car($list2))) { return 1; } else { return &member($list1,&cdr($list2)); } } } # sub LIGADURAS ------------------------------------------------------------ # -------------------------------------------------------------------------- # pag 373 # agrega una ligadura, dada expresion_var "?X", y dato para ligar sub agrega_ligadura { my $expresion_var = shift; my $dato = shift; my $ligaduras = shift; my $ultimo; if ( extrae_variable($expresion_var) eq "_" ) { return $ligaduras; } else { if (null($ligaduras)) { return cons([extrae_variable($expresion_var),$dato],$ligaduras); } else { $ultimo = length1($ligaduras); # agregar como ultimo $ligaduras->[$ultimo] = [&extrae_variable($expresion_var),$dato]; return $ligaduras; } } } # pag 373 # regresa el nombre de una variable sub extrae_variable { my $expresion_var = shift; return substr($expresion_var,1); } # pag 373 # regresa la llave de una ligadura sub extrae_llave { my $ligadura = shift; return car($ligadura); } # pag 373 # regresa el valor de una ligadura sub extrae_valor { my $ligadura = shift; return $ligadura->[1]; } # pag 374 # recibe una expresion_var "?X" y busca la var X en ligaduras # si la encuentra, regresa ligadura # si no, regresa NADA sub encuentra_ligadura { my $expresion_var = shift; my $ligaduras= shift; my $i=0; #print " "; #print "encuentra_ligadura: "; #print v($expresion_var) . " " . v($ligaduras); #print "\n"; if (null($expresion_var)) # ??? checa ligaduras { return; } # la variable "_" NO se liga if (&extrae_variable($expresion_var) eq "_" || null($ligaduras)) { # la variable "_" no se liga return; } else { for $i (0 .. length1($ligaduras)-1) { if (extrae_variable($expresion_var) eq extrae_llave($ligaduras->[$i])) { return $ligaduras->[$i]; } } } return; } # sub CORRESPONDE ---------------------------------------------------------- # -------------------------------------------------------------------------- # pag 378 # determina si los 2 parametros son atomicos sub elementos_p{ my $p = shift; my $d = shift; return atom($p) && !variable_p($p) && atom($d) && !variable_p($d); } # pag 378 # determina si el patron $p es una variable sub variable_p { my $p = shift; if (! $p) { return 0; } # ??? llegan valores nulos return atom($p)==1 && substr($p,0,1) eq "?" ? 1 : 0 ; } # pag 378 # determina si patron $p y dato $d son listas sub recursivos_p { my $p = shift; my $d = shift; return listp($p) && listp($d) ? 1 : 0; } # pag 377 sub corresponde_atomos { my $p = shift; my $d = shift; my $ligaduras =shift; if (eql($p,$d) || (null($p) && null($d))) { return $ligaduras; } else { # "falla"; return; } } # pag 377 sub corresponde_variable { my $p = shift; my $d = shift; my $ligaduras = shift; # $p no debe ser arreglo, sino variable my $ligadura; $ligadura = encuentra_ligadura($p,$ligaduras); if ($ligadura) { return corresponde(extrae_valor($ligadura),$d,$ligaduras); } else { return agrega_ligadura($p,$d,$ligaduras); } } # pag 377 sub corresponde_partes { my $p = shift; my $d = shift; my $ligaduras = shift; my $res; $res = corresponde(car($p),car($d),$ligaduras); if (! $res ) { # "NADA" return; } else { return corresponde(cdr($p),cdr($d),$res); } } # pag 373 sub corresponde { my $p=shift; my $d=shift; # { &opt $ligaduras my $ligaduras=shift; if (! $ligaduras) { $ligaduras = []; } # } if (elementos_p($p, $d)) { return corresponde_atomos($p,$d,$ligaduras); } if (variable_p($p)) { return corresponde_variable($p, $d, $ligaduras); } if (recursivos_p($p,$d)) { return corresponde_partes($p,$d,$ligaduras); } # "NADA"; return; } # sub UNIFICA -------------------------------------------------------------- # -------------------------------------------------------------------------- # pag 380 sub unifica { my $p1 = shift; my $p2 = shift; my $ligaduras = shift; # { &opt $ligaduras if (! $ligaduras) { $ligaduras = []; } # } if (elementos_p($p1,$p2)) { return unifica_atomos($p1,$p2,$ligaduras); } if (variable_p($p1)) { return unifica_variable($p1,$p2,$ligaduras); } if (variable_p($p2)) { return unifica_variable($p2,$p1,$ligaduras); } if (recursivos_p($p1,$p2)) { return unifica_partes($p1,$p2,$ligaduras); } # "NADA"; return; } # pag 380 sub unifica_atomos { my $p1 = shift; my $p2 = shift; my $ligaduras = shift; if (eql($p1,$p2)) {return $ligaduras;} else {return} } # pag 380 sub unifica_partes { my $p1 = shift; my $p2 = shift; my $ligaduras = shift; my $res; if (null($p1) && null($p2)) { return $ligaduras; } if (null($p1) || null($p2)) { return; } $res = unifica(car($p1),car($p2), $ligaduras); if (!$res) {return;} else {return unifica(cdr($p1),cdr($p2),$res);} # ??? } # pag 381 sub unifica_variable { my $p1 = shift; my $p2 = shift; my $ligaduras = shift; my $ligadura; $ligadura = &encuentra_ligadura($p1,$ligaduras); if ($ligadura) { return &unifica(&extrae_valor($ligadura),$p2,$ligaduras); } else { if (&contenido_p($p1,$p2,$ligaduras)) { # "falla"; return; } else { return agrega_ligadura($p1,$p2,$ligaduras); } } } # sub VARIABLES ------------------------------------------------------------ # -------------------------------------------------------------------------- # pag 381 sub contenido_p { my $variable = shift; my $expresion = shift; my $ligaduras = shift; if (equal($variable,$expresion)) { return 0; } else { return &contenido_o_igual_p($variable,$expresion,$ligaduras); } } # pag 382 sub contenido_o_igual_p { my $variable = shift; my $expresion = shift; my $ligaduras = shift; my $ligadura; if (equal($variable,$expresion)) { # t return 1; } if (&variable_p($expresion)) # ??? debe ir antes, por ser atomo { $ligadura = &encuentra_ligadura($expresion,$ligaduras); if ($ligadura) { return &contenido_o_igual_p($variable, extrae_valor($ligadura), $ligaduras); } } if (!$expresion || atom($expresion)) { # nil return 0; } return &contenido_o_igual_p($variable,car($expresion),$ligaduras) || &contenido_o_igual_p($variable,cdr($expresion),$ligaduras) ? 1 : 0; } # pag 419 sub particulariza_variables { my $patron = shift; my $lista_a = shift; my $t1; my $t2; my $t; if (variable_p($patron)) { $ligadura = encuentra_ligadura($patron,$lista_a); if ($ligadura) { $t1= particulariza_variables( extrae_valor($ligadura), $lista_a ); return $t1; } else { return $patron; } } else { if (atom($patron)) { return $patron; } else { return cons(particulariza_variables(car($patron),$lista_a), particulariza_variables(cdr($patron),$lista_a)); } } } # pag 420 # genera variables temporales unicas # ??? se devuelve con ?, como ?X3 sub gentemp { my $valor = shift; $c ++; return "?" . $valor .$c; } # sub FLUJOS --------------------------------------------------------------- # -------------------------------------------------------------------------- # pag 384 sub final_del_flujo_p { my $flujo = shift; return (equal($flujo,["vacio"])) ? 1: 0 ; } # pag 384 sub principio_del_flujo { my $flujo= shift; return car($flujo); } # pag 384 sub resto_del_flujo { my $flujo = shift; #if ( equal($flujo->[1],"registro(\$sth)")) #{ # eval $flujo->[1]; #} #else #{ # return $flujo->[1]; #} return car(cdr($flujo)); } # pag 384 sub construye_flujo { my $objeto = shift; my $flujo = shift; return list($objeto,$flujo); } # pag 384 # regresa la "concatenacion" de 2 flujos sub agrega_flujo { my $flujo1 = shift; my $flujo2 = shift; if (final_del_flujo_p($flujo1)) { return $flujo2; } else { return &construye_flujo(&principio_del_flujo($flujo1),&agrega_flujo(&resto_del_flujo($flujo1),$flujo2)); } } # pag 385 # regresa la concatenacion de un flujo de flujos sub concatena_flujo { my $flujos = shift; if (final_del_flujo_p($flujos)) { return ["vacio"]; } else { if (&final_del_flujo_p(&principio_del_flujo($flujos))) { return &concatena_flujo(&resto_del_flujo($flujos)); } else { return &construye_flujo( &principio_del_flujo(&principio_del_flujo($flujos)), &concatena_flujo(&construye_flujo(&resto_del_flujo(&principio_del_flujo($flujos)), &resto_del_flujo($flujos) ) ) ); } } } # pag 385 # regresa un flujo transformado mediante una funcion sub transforma_flujo { my $procedimiento = shift; my $flujo = shift; my $patron = shift; my $ligaduras = shift; if (&final_del_flujo_p($flujo)) { return ["vacio"]; } else { return construye_flujo( &$procedimiento(principio_del_flujo($flujo),$patron,$ligaduras), transforma_flujo($procedimiento,resto_del_flujo($flujo),$patron,$ligaduras)); } } # pag 385 sub miembro_de_flujo { my $objeto = shift; my $flujo = shift; if (final_del_flujo_p($flujo)) { return 0; } if (equal($objeto,principio_del_flujo($flujo))) { return 1; } return miembro_de_flujo($objeto,resto_del_flujo($flujo)); } # pag 385 # agrega un elemento al flujo, MODIFICANDO la variable de entrada $flujo # regresa el elemento agregado o NADA si esta en el flujo sub recuerda_flujo { my $valor = shift; my $flujo = shift; my $res; if (miembro_de_flujo($valor,$flujo)==1) { return; # NADA } else { $res=agrega_flujo($flujo,construye_flujo($valor,["vacio"])); $flujo->[0] = $res->[0]; # paso de parametros por referencia ??? $flujo->[1] = $res->[1]; return $valor; } } # sub ENCADENAMIENTO ------------------------------------------------------- # -------------------------------------------------------------------------- # sub AFIRMACIONES --------------------------------------------------------- # pag 409 # $afirmaciones es global # agrega afirmacion al flujo de $afirmaciones sub recuerda_afirmacion{ my $afirmacion = shift; return &recuerda_flujo($afirmacion,$afirmaciones); } # pag 414 sub intenta_afirmacion { my $patron = shift; my $afirmacion = shift; my $ligaduras = shift; my $res; # no habia el car # no habia copia $res= corresponde($patron,$afirmacion,$ligaduras); # eq "falla" ? if (!$res) { return ["vacio"]; } else { return construye_flujo($res,["vacio"]); } } # pag 414, pag 401 sub corresponde_patron_afirmaciones { my $patron = shift; my $ligaduras = shift; my $afirma = sub { my $afirmacion = shift; my $patron = shift; my $ligaduras = shift; # !!! copia($ligaduras) return intenta_afirmacion($patron,$afirmacion,copia($ligaduras)) }; return concatena_flujo(transforma_flujo($afirma, $afirmaciones,$patron,$ligaduras) ); } # sub REGLAS --------------------------------------------------------------- # pag 410 # $reglas es global # v(recuerda_regla("es azul")) -> ["es azul",["vacio"]] sub recuerda_regla{ my $regla = shift; return &recuerda_flujo($regla,$reglas); } # pag 415 sub corresponde_patron_reglas { my $patron = shift; my $ligaduras = shift; my $cpr_sub = sub { my $regla = shift; my $patron = shift; my $ligaduras = shift; return prueba_regla($patron,$regla,$ligaduras); }; return concatena_flujo(transforma_flujo($cpr_sub, $reglas,$patron,$ligaduras) ); } # pag 415 sub antecedentes_de_la_regla{ my $regla = shift; return &butlast(cdr($regla)); } # pag 415 sub nombre_de_la_regla { my $regla=shift; return &car($regla); } # pag 415 sub consecuente_de_la_regla { my $regla = shift; return &last1(&cdr($regla)); } # pag 415 sub prueba_regla { my $patron = shift; my $regla = shift; my $ligaduras = shift; my $regla2; $regla2 = haz_variables_unicas($regla); $res = unifica( $patron, &consecuente_de_la_regla($regla2), $ligaduras ); # eq "falla" ? if (!$res) { return ["vacio"]; } else { return &aplica_filtros( &antecedentes_de_la_regla($regla2), &construye_flujo($res,["vacio"]) ); } } # pag 420 sub haz_variables_unicas { my $regla = shift; my $variables; $variables = &lista_variables($regla); for $j (0..length1($variables)-1) { $regla=particulariza_variables( $regla, list(list($variables->[$j],gentemp($variables->[$j])))); } return $regla; } # pag 419 sub lista_variables { my $arbol = shift; my $nombres = shift; my $nomb; if (! $nombres ) { $nombres = []; } # variable_p antes de atom, ya que ?X es atom. if (variable_p($arbol)) { if (member(extrae_variable($arbol),$nombres)) { return $nombres; } else { return append($nombres,list(extrae_variable($arbol))); } } if (atom($arbol)) { return $nombres; } return &lista_variables( cdr($arbol), lista_variables(car($arbol),$nombres) ); } # sub ENCADENAMIENTO ------------------------------------------------------- # pag 413 sub aplica_filtros { my $patrones = shift; my $flujo_inicial = shift; if (null($patrones)) { return $flujo_inicial; } else { return aplica_filtros( cdr($patrones), filtra_flujo(car($patrones),$flujo_inicial) ); } } # pag 414 sub filtra_flujo { my $patron = shift; my $flujo = shift; my $ff_sub = sub { my $ligaduras = shift; my $patron = shift; my $cpa; my $cpr; return concatena_flujo( construye_flujo($cpa=corresponde_patron_afirmaciones($patron,$ligaduras), construye_flujo($cpr=corresponde_patron_reglas($patron,$ligaduras), ["vacio"] ) ) ); }; return concatena_flujo(transforma_flujo($ff_sub,$flujo,$patron)); } # pag 418 # recibe una lista de listas como argumento, es decir, recibe una lista de #listas en $patrones ejem. [["bozo","es","mamifero"]] sub encreg { my $patrones = shift; my $flujo_ligaduras; my $variables; my $resp_mostradas; my $f; $flujo_ligaduras =&aplica_filtros( $patrones, &construye_flujo([],["vacio"]) ); # print v($flujo_ligaduras)."\n"; $variables = &lista_variables($patrones); $resp_mostradas = []; if (&null($variables)) { if (&final_del_flujo_p($flujo_ligaduras)) { # print "no\n"; return "no"; } else { # print "si\n"; return "si"; } # como incremento $f, resto_del_flujo flujo_de_ligaduras } else { # como incremento $f, resto_del_flujo flujo_de_ligaduras for ( $f=$flujo_ligaduras; ! &final_del_flujo_p($f); $f=&resto_del_flujo($f) ) { $respuesta = &haz_respuesta( $variables, &principio_del_flujo($f)); if (!&member($respuesta,$resp_mostradas)) { # &muestra_respuestas($respuesta); $resp_mostradas=cons($respuesta,$resp_mostradas); } } # print "no_mas \n"; # return "no_mas"; return $resp_mostradas; } } # sub RESPUESTAS ----------------------------------------------------------- # pag 420 sub muestra_respuestas { my $respuestas = shift; for $i (0 .. $#{$respuestas}) { print "--> ". $respuestas->[$i][0] . " = ". $respuestas->[$i][1] ."\n"; } } # pag 419 sub haz_respuesta { my $variables = shift; my $ligaduras = shift; my $Resp; for $i (0..$#{$variables}) { $Resp->[$i][0] = $variables->[$i]; $Resp->[$i][1]="?" .$variables->[$i]; } return &particulariza_variables($Resp,$ligaduras); } # sub mSQL ----------------------------------------------------------------- # -------------------------------------------------------------------------- sub er { my $p=shift; my $BDD; my $Tabla; my $patron; my $dbh; $BDD = car($p); $Tabla = car((cdr($p))); $p=cdr(cdr($p)); $patron= [$p]; $sth=principio_de_la_base($BDD,$Tabla); print "$sth \n"; $afirmaciones=registro($sth); encreg($patron); } sub principio_de_la_base { my $BDD = shift; my $Tabla = shift; my $lineas; my $nombres; use Msql; $dbh= Connect Msql "127.0.0.1",$BDD; $sth= ListFields $dbh $Tabla; # !!! @nombres= @{$sth->name}; $sth= Query $dbh "select * from $Tabla"; $lineas = $sth->numrows; return $sth; } sub registro { my $sth = shift; my $resultado; @arr = FetchRow $sth; @nombres= @{$sth->name}; if (! @arr) { return ["vacio"]; } else { for ($i=0;$i<=$#arr;$i++) { # print "\n".$nombres[$i]."=".$arr[$i]."\t"; $resultado->[$i]=[$nombres[$i],$arr[$i]]; } } return construye_flujo($resultado,'registro($sth)'); } # sub DATOS ---------------------------------------------------------------- # -------------------------------------------------------------------------- sub datos_pag397 { # NO FUNCIONA, EXISTE UN CICLO RECURSIVO # POR TENER ?animal es ?especie # ANTES DE ?animal es ?padre de ?cria $reglas = ["vacio"]; $afirmaciones=["vacio"]; &recuerda_afirmacion(["bozo","es","perro"]); &recuerda_afirmacion(["deedee","es","caballo"]); &recuerda_afirmacion(["deedee","es","padre","de","sugar"]); recuerda_afirmacion(["deedee","es","padre","de","brassy"]); &recuerda_regla(["identifica",["?animal","es","?especie"], ["?animal","es","padre","de","?cria"], ["?cria","es","?especie"]]); return 1; } sub datos_pag397A { # YA FUNCIONA # POR TENER ?animal es ?especie # DESPUES DE ?animal es ?padre de ?cria $reglas = ["vacio"]; $afirmaciones=["vacio"]; &recuerda_afirmacion(["bozo","es","perro"]); &recuerda_afirmacion(["deedee","es","caballo"]); &recuerda_afirmacion(["deedee","es","padre","de","sugar"]); recuerda_afirmacion(["deedee","es","padre","de","brassy"]); &recuerda_regla(["identifica",["?animal","es","padre","de","?cria"], ["?animal","es","?especie"], ["?cria","es","?especie"]]); return 1; } sub datos_pag410 { $reglas = ["vacio"]; $afirmaciones=["vacio"]; recuerda_afirmacion(["deedee","tiene","pelo"]); recuerda_afirmacion(["bozo","es","mamifero"]); recuerda_regla(["identifica", ["?animal","tiene","pelo"],["?animal","es","mamifero"]]); return 1; } sub datos_pag420 { $afirmaciones=["vacio"]; recuerda_afirmacion(["robbie","tiene","manchas","oscuras"]); recuerda_afirmacion(["robbie","tiene","color","leonado"]); recuerda_afirmacion(["robbie","come","carne"]); recuerda_afirmacion(["robbie","tiene","pelo"]); recuerda_afirmacion(["suzie","tiene","plumas"]); recuerda_afirmacion(["suzie","vuela","bien"]); $reglas = ["vacio"]; recuerda_regla(["identifica1", ["?animal","tiene","pelo"], ["?animal","es","mamifero"]]); recuerda_regla(["identifica3", ["?animal","tiene","plumas"], ["?animal","es","ave"]]); recuerda_regla(["identifica5", ["?animal","come","carne"], ["?animal","es","carnivoro"]]); recuerda_regla(["identifica9", ["?animal","es","mamifero"], ["?animal","es","carnivoro"], ["?animal","tiene","color","leonado"], ["?animal","tiene","manchas","oscuras"], ["?animal","es","leopardo"]]); recuerda_regla(["identifica15", ["?animal","es","ave"], ["?animal","vuela","bien"], ["?animal","es","albatros"]]); return 1; } # sub INTERPRETE ----------------------------------------------------------- # -------------------------------------------------------------------------- sub inter{ $InPuT = 'no salir'; for (;;) { print '(',join(', ',@ReSuLt),') ?'; $InPuT = <STDIN>; chop $InPuT; $? = 0; $@ = ''; $! = 0; @ReSuLt = eval $InPuT; # if ($ReSuLt[0] eq "salir") die "Bye"; if ($?) { print 'status=',$?,' ' } if ($@) { print 'errmsg=',$@,' ' } if ($!) { print 'errno=',$!+0,': ',$!,' ' } } } # sub PRUEBAS -------------------------------------------------------------- # -------------------------------------------------------------------------- my $n=1187; # linea inicial de pruebas sub p { my $pru=shift; my $res=shift; if (equal(v($pru),v($res))) { print $n . " OK "; } else { print "\n" . $n . "->" . v($pru) . "\n < > " . v($res) ."\n"; } $n=$n+2; } p( list("uno",["dos"],[["tres"]],[]), ["uno",["dos"],[["tres"]],[]]); p( cons("uno",[]), ["uno"]); p( cons("uno",[[]]), ["uno",[]]); p( equal([["uno"],[["dos"]]],[["uno"],[["dos"]]]), 1); p( equal("uno","dos"), 0); p( equal([],[]), 1); p( equal("uno","uno"), 1); p( copia(["uno",[["dos"]]]), ["uno",[["dos"]]]); p( copia([]), []); p( append(["uno","dos",["tres"]],["cuatro",[["cinco"]]]), ["uno","dos",["tres"],"cuatro",[["cinco"]]]); p( $a=append([],[]), []); p( null([]), 1); p( null(["uno"]), 0); p( null([[]]), 0); p( [], []); p( ["uno",[["dos"]]], ["uno",[["dos"]]]); p( cdr([]), []); p( cdr(["uno"]), []); p( cdr(["uno","dos"]), ["dos"]); p( length1("a"), 0); p( length1([]), 0); p( length1(["uno","dos"]), 2); p( last1(["uno","dos"]), "dos"); p( last1(["uno",["dos"]]), ["dos"]); p( last1([]), 0); p( butlast(["uno","dos","tres"]), ["uno","dos"]); p( butlast(["uno","dos"]), ["uno"]); p( butlast(["uno",["dos"]]), ["uno"]); p( agrega_ligadura("?X","gato",[["Y","perro"]]), [["Y","perro"],["X","gato"]]); p( extrae_variable("?X"), "X"); p( extrae_llave(["X","perro"]), "X"); p( extrae_valor(["X","perro"]), "perro"); p( elementos_p("perro",[]), 1); p( elementos_p([],[]), 1); p( elementos_p("perro","gato"), 1); p( variable_p("?X"), 1); p( variable_p("X"), 0); p( recursivos_p(["uno"],"dos"), 0); p( recursivos_p(["uno"],[]), 1); p( encuentra_ligadura("?X",[["X","algo"],["Y","NO"]]), ["X","algo"]); p( encuentra_ligadura("?Z",[["X","algo"],["Y","NO"]]), 0); p( corresponde_atomos("uno","uno",[["X","perro"],["Y","gato"]]), [["X","perro"],["Y","gato"]]); p( corresponde_atomos("uno","dos",[["X","perro"],["Y","gato"]]), 0); p( corresponde_variable("?X","perro",[["X","perro"]]), [["X","perro"]]); p( corresponde_variable("?Y","gato",[["X","perro"]]), [["X","perro"],["Y","gato"]]); p( corresponde_variable("?X","gato",[["X","perro"]]), 0); p( corresponde_partes(["?X","?Y"],["perro","gato"],[["X","perro"]]), [["X","perro"],["Y","gato"]]); p( corresponde(["?X","?Y"],["perro","gato"],[["X","perro"]]), [["X","perro"],["Y","gato"]]); p( corresponde(["?X","?Y"],["perro","gato"],[["X","burro"]]), 0); p( corresponde(["?X","?Y"],["perro","gato"],[["Z","burro"]]), [["Z","burro"],["X","perro"],["Y","gato"]]); p( corresponde(["perro","?Y"],["perro","gato"],[["Z","burro"]]), [["Z","burro"],["Y","gato"]]); p( unifica(["?X","gato"],["perro","?Y"],[["X","perro"]]), [["X","perro"],["Y","gato"]]); p( unifica(["?X","?Y"],["perro","gato"],[["X","burro"]]), 0); p( unifica(["?X","gato"],["perro","?Y"],[["Z","burro"]]), [["Z","burro"],["X","perro"],["Y","gato"]]); p( unifica(["perro","?Z"],["perro","gato"],[["X","?Y"],["Y","?Z"]]), [["X","?Y"],["Y","?Z"],["Z","gato"]]); p( unifica_atomos("uno","uno",[["X","perro"],["Y","gato"]]), [["X","perro"],["Y","gato"]]); p( unifica_atomos("uno","dos",[["X","perro"],["Y","gato"]]), 0); p( unifica_partes(["?X","gato"],["perro","?Y"],[["X","perro"]]), [["X","perro"],["Y","gato"]]); p( contenido_p("?X", ["algo",[["?Y"]]],[["Y","?Z"],["Z","?X"]]), 1); p( contenido_p("?X",["?X"],[]), 1); p( contenido_p("?X","?X",[]), 0); p (construye_flujo("algo",["vacio"]), ["algo",["vacio"]]); p (agrega_flujo(["algo",["vacio"]],["otro",["vacio"]]), ["algo",["otro",["vacio"]]]); p (agrega_flujo(["objeto-A",["objeto-B",["vacio"]]],["objeto-X",["objeto-Y",["vacio"]]]), ["objeto-A",["objeto-B",["objeto-X",["objeto-Y",["vacio"]]]]]); p (concatena_flujo([["objeto-A",["objeto-B",["vacio"]]],[["objeto-X",["objeto-Y",["vacio"]]],["vacio"]]]), ["objeto-A",["objeto-B",["objeto-X",["objeto-Y",["vacio"]]]]]); p (miembro_de_flujo("objeto-A",["objeto-A",["objeto-B",["vacio"]]]), 1); p (miembro_de_flujo("ObjetoA",["objeto-A",["objeto-B",["vacio"]]]), 0); p ($flujo=["objeto-A",["objeto-B",["objeto-X",["objeto-Y",["vacio"]]]]], ["objeto-A",["objeto-B",["objeto-X",["objeto-Y",["vacio"]]]]]); p (recuerda_flujo("otro_mas",$flujo), "otro_mas"); p ($flujo, ["objeto-A",["objeto-B",["objeto-X",["objeto-Y",["otro_mas",["vacio"]]]]]]); p (recuerda_flujo("objeto-Y",$flujo), 0); p ($flujo=["objeto-A",["vacio"]], ["objeto-A",["vacio"]]); p (recuerda_flujo("otro_mas",$flujo), "otro_mas"); p ($flujo, ["objeto-A",["otro_mas",["vacio"]]]); p (recuerda_flujo("objeto-A",$flujo), 0); p ($flujo=["vacio"], ["vacio"]); p (recuerda_flujo("objeto-Y",$flujo), "objeto-Y"); p ($flujo, ["objeto-Y",["vacio"]]); p (datos_pag410(), 1); p ($afirmaciones, [["deedee","tiene","pelo"],[["bozo","es","mamifero"],["vacio"]]]); p ($reglas, [["identifica",["?animal","tiene","pelo"],["?animal","es","mamifero"]],["vacio"]]); p (aplica_filtros([["?animal","tiene","pelo"]],[[["animal","bozo"]],["vacio"]]), ["vacio"]); p (aplica_filtros([["?animal","tiene","pelo"]],[[["animal","deedee"]],["vacio"]]), [[["animal","deedee"]],["vacio"]]); p (datos_pag410(), 1); p ($afirmaciones, [["deedee","tiene","pelo"],[["bozo","es","mamifero"],["vacio"]]]); p ($reglas, [["identifica",["?animal","tiene","pelo"],["?animal","es","mamifero"]],["vacio"]]); p (corresponde_patron_afirmaciones(["bozo","es","mamifero"],[]), [[],["vacio"]]); # SI ES CIERTO p (corresponde_patron_afirmaciones(["?X","es","mamifero"],[]), [[["X","bozo"]],["vacio"]]); p (corresponde_patron_afirmaciones(["?X","es","mamifero"],[["X","otro"]]), ["vacio"]); p (datos_pag397(), 1); p ($afirmaciones, [["bozo","es","perro"],[["deedee","es","caballo"],[["deedee","es","padre","de","sugar"],[["deedee","es","padre","de","brassy"],["vacio"]]]]]); p ($reglas, [["identifica",["?animal","es","?especie"],["?animal","es","padre","de","?cria"],["?cria","es","?especie"]],["vacio"]]); p (corresponde_patron_afirmaciones(["?animal","es","?especie"],[]), [[["animal","bozo"],["especie","perro"]], [[["animal","deedee"],["especie","caballo"]],["vacio"]]]); p (corresponde_patron_afirmaciones(["?animal","es","padre","de","?cria"],[["especie","caballo"],["animal","deedee"]]), [[["especie","caballo"],["animal","deedee"],["cria","sugar"]],[[["especie","caballo"],["animal","deedee"],["cria","brassy"]],["vacio"]]]); p (datos_pag410(), 1); p ($afirmaciones, [["deedee","tiene","pelo"],[["bozo","es","mamifero"],["vacio"]]]); p ($reglas, [["identifica",["?animal","tiene","pelo"],["?animal","es","mamifero"]],["vacio"]]); p (intenta_afirmacion(["bozo","es","mamifero"],["bozo","es","mamifero"],[]), [[],["vacio"]]); p (intenta_afirmacion(["bozo","es","mamifero"],["deedee","tiene","pelo"],[]), ["vacio"]); p (corresponde_patron_reglas(["bozo","no","hace match"],["vacio"]), ["vacio"]); p (corresponde_patron_reglas(["bozo","es","mamifero"],[]), ["vacio"]); p (corresponde_patron_reglas(["otro","es","mamifero"],[]), ["vacio"]); p (corresponde_patron_reglas(["deedee","es","mamifero"],[]), [[["animal8","deedee"]],["vacio"]]); p (car($reglas), ["identifica",["?animal","tiene","pelo"],["?animal","es","mamifero"]]); p (nombre_de_la_regla(car($reglas)), "identifica"); p (antecedentes_de_la_regla(car($reglas)), [["?animal","tiene","pelo"]]); p (consecuente_de_la_regla(car($reglas)), ["?animal","es","mamifero"]); p (haz_variables_unicas(car($reglas)), ["identifica",["?animal10","tiene","pelo"],["?animal10","es","mamifero"]]); p (lista_variables(["?X"],[]), ["X"]); p (lista_variables(["?X","?Y",[["?Z","es",[[["?W","?A"]]]]]],["A"]), ["A","X","Y","Z","W"]); p (haz_respuesta(["x"],[["animal","deedee"],["x","?animal"]]), [["x","deedee"]]); p (particulariza_variables(["?uno","dos","tres"],[["uno","one"]]), ["one","dos","tres"]); p (particulariza_variables(["X","?X"],[["animal","deedee"],["X","?animal"]]), ["X","deedee"]); p (particulariza_variables("?animal",[["animal","deedee"]]), "deedee"); p (particulariza_variables("X",[["animal","deedee"],["X","?animal"]]), "X"); p (gentemp("X"), "?X11"); p (datos_pag410(), 1); p (encreg([["bozo","es","mamifero"]]), "si"); p (encreg([["bozo","no","hace match"]]), "no"); p (encreg([["otro","es","mamifero"]]), "no"); p (encreg([["?x","es","mamifero"]]), [[["x","deedee"]],[["x","bozo"]]]); p (datos_pag420(), 1); p (encreg([["?q","es","?a"]]), [[["q","suzie"],["a","albatros"]],[["q","robbie"],["a","leopardo"]],[["q","robbie"],["a","carnivoro"]],[["q","suzie"],["a","ave"]],[["q","robbie"],["a","mamifero"]]]); p (datos_pag397A(), 1); p (encreg([["?q","es","padre","de","brassy"]]), [[["q","deedee"]]]); p (encreg([["?q","es","padre","de","?o"]]), [[["q","deedee"],["o","brassy"]],[["q","deedee"],["o","sugar"]]]); p (encreg([["bozo","es","perro"]]), "si"); p (encreg([["?q","es","perro"]]), [[["q","bozo"]]]); p (encreg([["?q","es","caballo"]]), [[["q","brassy"]],[["q","sugar"]],[["q","deedee"]]]); p (encreg([["deedee","es","padre","?x"]]), []); p (encreg([["deedee","es","padre","de","?x"]]), [[["x","brassy"]],[["x","sugar"]]]); print "\n"; inter(); </pre></body></html>