Algoritmo secuencial
A diferencia del algoritmo RetePlus , la modalidad de ejecución secuencial no proporciona inferencia. El algoritmo secuencial sólo funciona de forma predecible cuando las reglas son homogéneas, es decir, cuando utilizan los mismos enlaces.
Para garantizar la misma ejecución con cualquiera de los algoritmos, se requieren las dos condiciones siguientes:
Las reglas deben ser homogéneas. Las reglas homogéneas significan que las condiciones de esas reglas deben establecerse en el mismo tipo y número de objetos. Si intenta aplicar el algoritmo secuencial a reglas heterogéneas, normalmente crea más objetos de tupla, lo que puede hacer que se ejecuten más reglas que en la modalidad RetePlus . La firma de tupla común también puede provocar que no se activen reglas heterogéneas: cuando no hay instancias correspondientes en la memoria de trabajo, no se pueden crear tuplas.
Las reglas no deben encadenarse, es decir, la modificación realizada en la parte de acción de una regla no debe llevar a la ejecución de otra regla.
Si especifica la modalidad de ejecución secuencial para reglas que no son compatibles con ella, el motor genera un error.
El uso de la modalidad de ejecución secuencial se describe más adelante en las secciones:
Tuplas
Una tupla es una lista de objetos que cumple con una estructura determinada. Una estructura de tupla es simplemente una secuencia de descriptores de clase. Cada ubicación de una estructura de tupla se denomina ranura. El mismo descriptor de clase puede aparecer más de una vez en diferentes ranuras.
Tome una estructura de tupla:
(Customer,Product)
Aquí hay una tupla que cumple con esta estructura:
(new Customer("Henry"),new DVD("Mickey"))
Tenga en cuenta que la subclase se tiene en cuenta porque un DVD es un Product. Sin embargo, algunas tuplas que no cumplen con la estructura:
Por ejemplo, la siguiente tupla es demasiado grande:
(new Customer("Henry"),new CD("Madona"),new DVD("Mickey"))
Esta tupla no está ordenada correctamente:
(new DVD("Lord of the rings"),new Customer("Henry"))
Y esta tupla es demasiado pequeña:
(new Customer("Henry"))
En Java™, una tupla se implementa fácilmente como una matriz de objetos:
Java Tuple = Object[]
El código Java para crear una tupla y sus objetos es:
new Object[] {new Customer("Henry"),new DVD("Mickey")}
En tiempo de ejecución, las tuplas se crean a mano o automáticamente a partir del contenido de la memoria de trabajo y, a continuación, se pasan al motor de reglas. Las tuplas se pasan una tras otra al método de coincidencia de tuplas.
Las tuplas se construyen a partir de los objetos de la memoria de trabajo sólo si coinciden con la estructura de tupla: una firma común que comparten todas las reglas de la tarea secuencial. Después de la generación de tuplas, todas las reglas se ejecutan en todas las tuplas. Por lo tanto, se recomienda utilizar reglas homogéneas con el algoritmo secuencial.
Si proporciona su propia tupla, siempre debe coincidir con la firma, pero no necesariamente tiene que estar completa. Una tupla parcial es una tupla con ranuras no utilizadas. Las ranuras no utilizadas simplemente se establecen en un valor nulo. Por ejemplo, la tupla(new Customer("Henry")) que era demasiado pequeña se podría codificar como (new Customer("Henry"),null) para poder satisfacer la estructura de la tupla.
rule r1 {
when{
Integer();
Integer();
}
then {...
rule r2 {
when{
Integer();
}
then {...rule r1 {
when{
Integer();
String();
}
then {...
rule r2 {
when{
Integer();
}
then {...Selección de reglas en modalidad secuencial
Las reglas de una tarea de regla que se establecen con la propiedad algorithm igual a sequential se convierten dinámicamente en código de bytes Java. El código de bytes es capaz de realizar un proceso secuencial cuando se ejecuta la tarea.
La propiedad body de una tarea de regla es obligatoria. Selecciona las reglas del conjunto de reglas que la tarea de reglas tiene en cuenta.
Consulte también Selección de reglas de tiempo de ejecución.
Propiedades de control en modalidad secuencial
Las propiedades de control afectan a la ejecución en modalidad secuencial y a la estructura de tupla. Consulte Propiedades de control para tareas de reglas en modalidades de ejecución para obtener más información general.
El número de reglas que se deben ejecutar por tupla y el orden en el que se ejecutan se pueden especificar con las propiedades de control: orden, activacióny firinglimit.
La propiedad de ordenación
La propiedad ordering es obligatoria para el proceso secuencial. Describe el orden en el que se ejecutarán las reglas de la tarea de regla.
Hay dos valores disponibles:
literal: las reglas se mantienen en el orden en el que se establecen en el cuerpo de la tarea (utilizando flechas arriba/abajo).sorted: las reglas se ordenan según sus prioridades estáticas.
Tenga en cuenta que otro valor, dynamic, sólo está disponible para las tareas de regla que utilizan la modalidad de ejecución RetePlus .
La propiedad de activación
La propiedad firing especifica si, para cada tupla, se deben ejecutar todas las reglas o sólo la primera regla que se aplica. Esta propiedad es opcional.
Tiene dos valores posibles:
allrulesEste valor significa que todas las reglas que se aplican deben ejecutarse antes de saltarse a la siguiente tupla. Este es el valor predeterminado.
ruleEste valor significa que sólo se debe ejecutar la primera regla que se aplica en la primera tupla.
La propiedad firinglimit
La propiedad firinglimit proporciona otro nivel de control cuando la propiedad firing se establece en allrules. Se utiliza para especificar un número que representa el número máximo de reglas que se deben ejecutar antes de saltar a la siguiente tupla. Este número debe ser mayor que cero.
Limitaciones conocidas del algoritmo secuencial
En casi todos los casos no hay limitación en el número de reglas manejadas por una sola tarea que tiene una propiedad de algoritmo igual a secuencial. La única excepción es con tablas de decisiones extremadamente grandes con un otherwise. El proceso es el siguiente: todas las condiciones de todas las líneas se niegan en una sola expresión. Esta expresión única se convierte en el cuerpo de un único método una vez traducido al código de bytes. Esto es un problema porque el verificador Java rechaza los métodos con un cuerpo demasiado grande. El algoritmo de escalabilidad utilizado para las reglas no se reduce al cuerpo del método. Se notifica al usuario de esta limitación cuando el cargador de clases rechaza las reglas. El límite en el número de reglas no es claro, pero es probable que el número sea de varios miles.
La tabla siguiente describe las limitaciones del proceso secuencial, en particular su uso combinado con determinadas construcciones de ILOG ® Rule Language (IRL).
| Limitación | Descripción |
|---|---|
| Limitaciones de ILOG Rule Language (IRL) | No todos los patrones de reglas que se han diseñado para la coincidencia de Rete con estado están disponibles. Los errores de tiempo de compilación se producen cuando una regla no es compatible con la implementación de coincidencia de tupla actual. Por lo tanto, cuando se utiliza el proceso secuencial, IRL no da soporte a las características siguientes:
|
| Construcciones de condición | Las siguientes construcciones de condición están disponibles en el proceso secuencial:
|
| Manejo de excepciones | El manejo de excepciones no está soportado en las partes de condición de regla en las modalidades secuencial y de vía de acceso rápida. Por ejemplo, si especifica un manejador de excepciones en un contexto, no se tiene en cuenta en las modalidades secuencial y Fastpath:
|
| Refracción | La unidad de datos para un ciclo de motor es la tupla. El motor no registra las tuplas ya que están emparejadas, más bien las olvida entre ciclos. Por lo tanto, no hay soporte incorporado para la refracción. Utilizando la modalidad de ejecución secuencial, la tarea de regla anterior se convierte en:
La estructura de tupla calculada:
El código de coincidencia de tupla generado:
El código principal sigue siendo el mismo:
Bucle de iterador de memoria de trabajo:
El rastreo de ejecución:
El rastreo de ejecución muestra que, utilizando la modalidad de ejecución secuencial, la misma regla se ejecuta dos veces para las mismas partes de dos tuplas diferentes. |
| Recursos IRL (ILOG Rule Language) | Por el contrario, prácticamente todas las expresiones y sentencias de nivel de script del IRL están disponibles en el proceso secuencial. Sirven principalmente para mantener la coherencia de las otras tareas de regla que no están establecidas en el algoritmo secuencial. A continuación se muestra una lista de estas características:
|
Los ejemplos siguientes muestran casos que causan errores de compilación JIT (Just-In-Time), es decir, un error en tiempo de ejecución en lugar de un error de análisis.
Ejemplo 1: Limitación de IRL que provoca un error de compilación
Este ejemplo da como resultado errores de compilación JIT debido a que faltan enumeradores.
ruletask T {
algorithm = sequential;
body = { R1, R2, R3, R4, R5, R6, R7, R8, R9 }
}
rule R1 {
when {
not MyObject(); // No enumerator, an error will occur
}
then {
}
}
rule R2 {
when {
exists MyObject(); // No enumerator, an error will occur
}
then {
}
}
rule R3 {
when {
collect MyObject() where (size() == 1); // No enumerator, an error
will occur
}
then {
}
}
function Object getObject() {
return new MyObject();
}
function Object[] getObjects() {
Object objs = new Object[1];
objs[0] = getObject();
return objs;
}
rule R4 {
when {
not MyObject() from getObject(); // An enumerator, no error
}
then {
}
}
rule R5 {
when {
not MyObject() in getObjects(); // An enumerator, no error
}
then {
}
}
rule R6 {
when {
exists MyObject() from getObject(); // An enumerator, no error
}
then {
}
}
rule R7 {
when {
exists MyObject() in getObjects(); // An enumerator, no error
}
then {
}
}
rule R8 {
when {
collect MyObject() from getObject() where (size() == 1);
// An enumerator, no error
}
then {
}
}
rule R9 {
when {
collect MyObject() in getObjects() where (size() == 1);
// An enumerator, no error
}
then {
}
}
Ejemplo 2: IRL que muestra limitaciones de construcción
A continuación se muestra un ejemplo con una construcción collect para mostrar el ámbito de los enlaces. Esto también se mantiene para not y exists . Este ejemplo también genera errores de compilación JIT debido al uso de construcciones no soportadas.
rule R10 {
when {
r:MyRootObject();
c:collect MyObject(n:name; n.startsWith("ilog")) in r.getObjects();
where (s:size(); s > 1);
}
then {
out.println(r); // correct
out.println(c); // correct
out.println(s); // correct
out.println(n); // error
}
}