Author: vmorari
Date: Fri Jan 11 15:26:46 2019
New Revision: 1851060

URL: http://svn.apache.org/viewvc?rev=1851060&view=rev
Log:
UIMA-5955: allowed multiple inlined rule blocks. added test.

Modified:
    
uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
    
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/AbstractRuleElement.java
    
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RuleElement.java
    
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java
    
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
    
uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/rule/InlinedRulesTest.java

Modified: 
uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
 Fri Jan 11 15:26:46 2019
@@ -998,7 +998,7 @@ String label = null;
        re1 = ruleElementAnnotationType[container] {re = re1;}
        | re2 = ruleElementLiteral[container] {re = re2;}
        | (ruleElementComposed[null])=>re3 = ruleElementComposed[container] {re 
= re3;}
-       | (ruleElementWildCard[null])=> re5 = ruleElementWildCard[container] 
{re = re5;}
+       | (ruleElementWildCard[null])=> re4 = ruleElementWildCard[container] 
{re = re4;}
        | (ruleElementOptional[null])=> re5 = ruleElementOptional[container] 
{re = re5;}
        )
        {
@@ -1006,18 +1006,19 @@ String label = null;
        re.setStartAnchor(start != null);
        }
        (t = (THEN2) 
+       {innerConditionRules = new ArrayList<RutaStatement>();}
        LCURLY 
        (rule = simpleStatement {innerConditionRules.add(rule);})+ 
        RCURLY 
-       {re.setInlinedConditionRules(innerConditionRules);}
-
-       )?
-       (t = (THEN) 
+       {re.addInlinedConditionRules(innerConditionRules);}
+       )*
+       (t = (THEN)
+       {innerActionRules = new ArrayList<RutaStatement>();} 
        LCURLY 
        (rule = simpleStatement {innerActionRules.add(rule);})+ 
        RCURLY 
-       {re.setInlinedActionRules(innerActionRules);}
-       )?
+       {re.addInlinedActionRules(innerActionRules);}
+       )*
        ;       
 
 ruleElementWildCard [RuleElementContainer container] returns 
[AbstractRuleElement re = null]

Modified: 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/AbstractRuleElement.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/AbstractRuleElement.java?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/AbstractRuleElement.java
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/AbstractRuleElement.java
 Fri Jan 11 15:26:46 2019
@@ -54,9 +54,9 @@ public abstract class AbstractRuleElemen
   @SuppressWarnings("unchecked")
   protected final InferenceCrowd emptyCrowd = new 
InferenceCrowd(Collections.EMPTY_LIST);
 
-  protected List<RutaStatement> inlinedConditionRules;
+  protected List<List<RutaStatement>> inlinedConditionRuleBlocks = new 
ArrayList<>();
 
-  protected List<RutaStatement> inlinedActionRules;
+  protected List<List<RutaStatement>> inlinedActionRuleBlocks = new 
ArrayList<>();
 
   public AbstractRuleElement(RuleElementQuantifier quantifier,
           List<AbstractRutaCondition> conditions, List<AbstractRutaAction> 
actions,
@@ -89,25 +89,25 @@ public abstract class AbstractRuleElemen
     }
   }
 
-  protected List<ScriptApply> processInlinedActionRules(RuleMatch ruleMatch, 
RutaStream stream,
+  protected List<List<ScriptApply>> processInlinedActionRules(RuleMatch 
ruleMatch, RutaStream stream,
           InferenceCrowd crowd) {
-    if (inlinedActionRules != null && !inlinedActionRules.isEmpty()) {
-      return processInlinedRules(inlinedActionRules, ruleMatch, stream, crowd);
+    if (inlinedActionRuleBlocks != null && !inlinedActionRuleBlocks.isEmpty()) 
{
+      return processInlinedRules(inlinedActionRuleBlocks, ruleMatch, stream, 
crowd);
     }
     return null;
   }
 
-  protected List<ScriptApply> processInlinedConditionRules(RuleMatch 
ruleMatch, RutaStream stream,
+  protected List<List<ScriptApply>> processInlinedConditionRules(RuleMatch 
ruleMatch, RutaStream stream,
           InferenceCrowd crowd) {
-    if (inlinedConditionRules != null && !inlinedConditionRules.isEmpty()) {
-      return processInlinedRules(inlinedConditionRules, ruleMatch, stream, 
crowd);
+    if (inlinedConditionRuleBlocks != null && 
!inlinedConditionRuleBlocks.isEmpty()) {
+      return processInlinedRules(inlinedConditionRuleBlocks, ruleMatch, 
stream, crowd);
     }
     return null;
   }
 
-  protected List<ScriptApply> processInlinedRules(List<RutaStatement> 
inlinedRules,
+  protected List<List<ScriptApply>> 
processInlinedRules(List<List<RutaStatement>> inlinedRuleBlocks,
           RuleMatch ruleMatch, RutaStream stream, InferenceCrowd crowd) {
-    List<ScriptApply> result = new ArrayList<ScriptApply>();
+    List<List<ScriptApply>> result = new ArrayList<>();
     List<AnnotationFS> matchedAnnotationsOf = 
ruleMatch.getMatchedAnnotationsOfElement(this);
     // TODO where to implement the explanation of inlined rules?
     // BlockApply blockApply = new BlockApply(this);
@@ -116,11 +116,15 @@ public abstract class AbstractRuleElemen
     // ruleMatch.addDelegateApply(this, blockApply);
     for (AnnotationFS annotationFS : matchedAnnotationsOf) {
       RutaStream windowStream = stream.getWindowStream(annotationFS, 
annotationFS.getType());
-      for (RutaStatement each : inlinedRules) {
-        ScriptApply apply = each.apply(windowStream, crowd);
-        // blockApply.add(apply);
-        ruleMatch.addDelegateApply(this, apply);
-        result.add(apply);
+      for (List<RutaStatement> inlinedRules : inlinedRuleBlocks) {
+        List<ScriptApply> blockResult = new ArrayList<>();
+        for (RutaStatement each : inlinedRules) {
+          ScriptApply apply = each.apply(windowStream, crowd);
+          // blockApply.add(apply);
+          ruleMatch.addDelegateApply(this, apply);
+          blockResult.add(apply);
+        }
+        result.add(blockResult);
       }
     }
     return result;
@@ -138,11 +142,19 @@ public abstract class AbstractRuleElemen
 
   protected boolean matchInnerRules(RuleMatch ruleMatch, RutaStream stream, 
InferenceCrowd crowd) {
 
-    List<ScriptApply> list = processInlinedConditionRules(ruleMatch, stream, 
crowd);
-    if (list == null) {
+    List<List<ScriptApply>> blockResults = 
processInlinedConditionRules(ruleMatch, stream, crowd);
+    if (blockResults == null) {
       return true;
     }
+    
+    boolean matched = true;
+    for (List<ScriptApply> list : blockResults) {
+      matched &= atLeastOneRuleMatched(list);
+    }
+    return matched;
+  }
 
+  private boolean atLeastOneRuleMatched(List<ScriptApply> list) {
     for (ScriptApply scriptApply : list) {
       if (scriptApply instanceof RuleApply) {
         RuleApply ra = (RuleApply) scriptApply;
@@ -310,23 +322,23 @@ public abstract class AbstractRuleElemen
   }
 
   @Override
-  public void setInlinedConditionRules(List<RutaStatement> innerRules) {
-    this.inlinedConditionRules = innerRules;
+  public void addInlinedConditionRules(List<RutaStatement> innerRules) {
+    this.inlinedConditionRuleBlocks.add(innerRules);
   }
 
   @Override
-  public List<RutaStatement> getInlinedConditionRules() {
-    return inlinedConditionRules;
+  public List<List<RutaStatement>> getInlinedConditionRuleBlocks() {
+    return inlinedConditionRuleBlocks;
   }
 
   @Override
-  public void setInlinedActionRules(List<RutaStatement> innerRules) {
-    this.inlinedActionRules = innerRules;
+  public void addInlinedActionRules(List<RutaStatement> innerRules) {
+    this.inlinedActionRuleBlocks.add(innerRules);
   }
 
   @Override
-  public List<RutaStatement> getInlinedActionRules() {
-    return inlinedActionRules;
+  public List<List<RutaStatement>> getInlinedActionRuleBlocks() {
+    return inlinedActionRuleBlocks;
   }
 
 }

Modified: 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RuleElement.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RuleElement.java?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RuleElement.java
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RuleElement.java
 Fri Jan 11 15:26:46 2019
@@ -78,16 +78,16 @@ public interface RuleElement {
 
   boolean isStartAnchor();
 
-  void setInlinedActionRules(List<RutaStatement> innerRules);
+  void addInlinedActionRules(List<RutaStatement> innerRules);
 
-  void setInlinedConditionRules(List<RutaStatement> innerRules);
+  void addInlinedConditionRules(List<RutaStatement> innerRules);
 
   void setLabel(String label);
 
   String getLabel();
   
-  List<RutaStatement> getInlinedConditionRules();
+  List<List<RutaStatement>> getInlinedConditionRuleBlocks();
   
-  List<RutaStatement> getInlinedActionRules();
+  List<List<RutaStatement>> getInlinedActionRuleBlocks();
 
 }

Modified: 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java 
(original)
+++ 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRule.java 
Fri Jan 11 15:26:46 2019
@@ -109,8 +109,8 @@ public class RutaRule extends AbstractRu
         fillLabelMap(each);
       }
     }
-    fillLabelMapWithInlinedRules(ruleElement.getInlinedConditionRules());
-    fillLabelMapWithInlinedRules(ruleElement.getInlinedActionRules());
+    fillLabelMapWithInlinedRules(ruleElement.getInlinedConditionRuleBlocks());
+    fillLabelMapWithInlinedRules(ruleElement.getInlinedActionRuleBlocks());
   }
 
   private void fillLabelMapWithActions(List<AbstractRutaAction> actions) {
@@ -123,13 +123,15 @@ public class RutaRule extends AbstractRu
     }
   }
 
-  private void fillLabelMapWithInlinedRules(List<RutaStatement> rules) {
-    if (rules != null) {
-      for (RutaStatement eachInlined : rules) {
-        if (eachInlined instanceof RutaRule) {
-          RutaRule inlinedRule = (RutaRule) eachInlined;
-          inlinedRule.setInlined(true);
-          fillLabelMap(inlinedRule.getRoot());
+  private void fillLabelMapWithInlinedRules(List<List<RutaStatement>> blocks) {
+    if (blocks != null) {
+      for (List<RutaStatement> list : blocks) {
+        for (RutaStatement eachInlined : list) {
+          if (eachInlined instanceof RutaRule) {
+            RutaRule inlinedRule = (RutaRule) eachInlined;
+            inlinedRule.setInlined(true);
+            fillLabelMap(inlinedRule.getRoot());
+          }
         }
       }
     }

Modified: 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
 Fri Jan 11 15:26:46 2019
@@ -207,23 +207,27 @@ public class ScriptVerbalizer {
     }
     if (re instanceof AbstractRuleElement) {
       AbstractRuleElement are = (AbstractRuleElement) re;
-      List<RutaStatement> inlinedConditionRules = 
are.getInlinedConditionRules();
-      if (inlinedConditionRules != null && !inlinedConditionRules.isEmpty()) {
-        result.append(THEN2);
-        result.append(CBOPEN);
-        for (RutaStatement rutaStatement : inlinedConditionRules) {
-          result.append(verbalize(rutaStatement));
+      List<List<RutaStatement>> inlinedConditionRuleBlocks = 
are.getInlinedConditionRuleBlocks();
+      for (List<RutaStatement> inlinedConditionRules : 
inlinedConditionRuleBlocks) {
+        if (inlinedConditionRules != null && !inlinedConditionRules.isEmpty()) 
{
+          result.append(THEN2);
+          result.append(CBOPEN);
+          for (RutaStatement rutaStatement : inlinedConditionRules) {
+            result.append(verbalize(rutaStatement));
+          }
+          result.append(CBCLOSE);
         }
-        result.append(CBCLOSE);
       }
-      List<RutaStatement> inlinedActionRules = are.getInlinedActionRules();
-      if (inlinedActionRules != null && !inlinedActionRules.isEmpty()) {
-        result.append(THEN);
-        result.append(CBOPEN);
-        for (RutaStatement rutaStatement : inlinedActionRules) {
-          result.append(verbalize(rutaStatement));
+      List<List<RutaStatement>> inlinedActionRuleBlocks = 
are.getInlinedActionRuleBlocks();
+      for (List<RutaStatement> inlinedActionRules : inlinedActionRuleBlocks) {
+        if (inlinedActionRules != null && !inlinedActionRules.isEmpty()) {
+          result.append(THEN);
+          result.append(CBOPEN);
+          for (RutaStatement rutaStatement : inlinedActionRules) {
+            result.append(verbalize(rutaStatement));
+          }
+          result.append(CBCLOSE);
         }
-        result.append(CBCLOSE);
       }
     }
     return result.toString();

Modified: 
uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/rule/InlinedRulesTest.java
URL: 
http://svn.apache.org/viewvc/uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/rule/InlinedRulesTest.java?rev=1851060&r1=1851059&r2=1851060&view=diff
==============================================================================
--- 
uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/rule/InlinedRulesTest.java
 (original)
+++ 
uima/ruta/trunk/ruta-core/src/test/java/org/apache/uima/ruta/rule/InlinedRulesTest.java
 Fri Jan 11 15:26:46 2019
@@ -19,73 +19,75 @@
 
 package org.apache.uima.ruta.rule;
 
+import java.io.IOException;
+
 import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.ruta.engine.Ruta;
 import org.apache.uima.ruta.engine.RutaTestUtils;
+import org.apache.uima.util.InvalidXMLException;
 import org.junit.Test;
 
 public class InlinedRulesTest {
 
   @Test
-  public void test() {
+  public void test() throws Exception {
     String document = "The Ruta language is an imperative rule language 
extended with scripting elements. A Ruta rule defines a pattern of annotations 
with additional conditions. If this pattern applies, then the actions of the 
rule are performed  on the matched annotations. A rule is composed of a 
sequence of rule elements and a rule element essentially consists of four 
parts: A matching condition, an optional quantifier, a list of conditions and a 
list of actions. The matching condition is typically a type of an annotation by 
which the rule element matches on the covered text of one of those annotations. 
The quantifier specifies, whether it is necessary that the rule element 
successfully matches and how often the rule element may match. The list of 
conditions specifies additional constraints that the matched text or 
annotations need to fulfill. The list of actions defines the consequences of 
the rule and often creates new annotations or modifies existing annotations.";
     String script = "";
     script += "PERIOD #{-> T1} @PERIOD;\n";
     script += "#{-> T1} PERIOD;\n";
-     // inlined as block
-     script += "T1{STARTSWITH(Document)}->{CW{->T2};};\n";
-     script += "(T1 PERIOD T1){CONTAINS(COLON)}->{COMMA #{->T3} COMMA; COLON 
ANY{-> T4};};\n";
-     script += "(COLON # COMMA)->{ANY{REGEXP(\"a.*\", true)-> T5};};";
-     // inlined as condition
-     script += "T1{->T6}<-{ANY COLON ANY{->T6};};\n";
-     script += "T1{->T7}<-{CW COLON CW{->T7};};\n";
-     script +=
-     "(T1 PERIOD{ -> T8} T1){CONTAINS(COLON)}<-{CW COLON CW{->T9}; COLON 
ANY{-> T10};};\n";
-     script += "(T1 PERIOD{ -> T11} T1){CONTAINS(COLON)}<-{CW COLON 
CW{->T11};};\n";
-     script +=
-     "(T1 PERIOD T1{-> T12}){CONTAINS(COLON)}<-{W COLON (W 
W)<-{ANY{REGEXP(\"match.*\")};};};\n";
+    // inlined as block
+    script += "T1{STARTSWITH(Document)}->{CW{->T2};};\n";
+    script += "(T1 PERIOD T1){CONTAINS(COLON)}->{COMMA #{->T3} COMMA; COLON 
ANY{-> T4};};\n";
+    script += "(COLON # COMMA)->{ANY{REGEXP(\"a.*\", true)-> T5};};";
+    // inlined as condition
+    script += "T1{->T6}<-{ANY COLON ANY{->T6};};\n";
+    script += "T1{->T7}<-{CW COLON CW{->T7};};\n";
+    script += "(T1 PERIOD{ -> T8} T1){CONTAINS(COLON)}<-{CW COLON CW{->T9}; 
COLON ANY{-> T10};};\n";
+    script += "(T1 PERIOD{ -> T11} T1){CONTAINS(COLON)}<-{CW COLON 
CW{->T11};};\n";
+    script += "(T1 PERIOD T1{-> T12}){CONTAINS(COLON)}<-{W COLON (W 
W)<-{ANY{REGEXP(\"match.*\")};};};\n";
     // both types
     script += "T1<-{W COLON W W;}->{COLON{->T13};};\n";
     script += "(T1 PERIOD T1){CONTAINS(COLON)}<-{W COLON (W 
W)<-{ANY{REGEXP(\"match.*\")};}->{W{->T14};};};\n";
-    CAS cas = null;
-    try {
-      cas = RutaTestUtils.getCAS(document);
-      Ruta.apply(cas, script);
-    } catch (Exception e) {
-    }
+    CAS cas = RutaTestUtils.getCAS(document);
+    Ruta.apply(cas, script);
 
     RutaTestUtils.assertAnnotationsEquals(cas, 2, 2, "The", "Ruta");
-    RutaTestUtils
-            .assertAnnotationsEquals(
-                    cas,
-                    3,
-                    3,//
-                    "then the actions of the rule are performed  on the 
matched annotations. A rule is composed of a sequence of rule elements and a 
rule element essentially consists of four parts: A matching condition",
-                    "an optional quantifier", "an optional quantifier");
+    RutaTestUtils.assertAnnotationsEquals(cas, 3, 3, //
+            "then the actions of the rule are performed  on the matched 
annotations. A rule is composed of a sequence of rule elements and a rule 
element essentially consists of four parts: A matching condition",
+            "an optional quantifier", "an optional quantifier");
     RutaTestUtils.assertAnnotationsEquals(cas, 4, 2, "A", "A");
     RutaTestUtils.assertAnnotationsEquals(cas, 5, 1, "A");
-    RutaTestUtils
-            .assertAnnotationsEquals(
-                    cas,
-                    6,
-                    2, //
-                    "A rule is composed of a sequence of rule elements and a 
rule element essentially consists of four parts: A matching condition, an 
optional quantifier, a list of conditions and a list of actions",
-                    "A");
+    RutaTestUtils.assertAnnotationsEquals(cas, 6, 2, //
+            "A rule is composed of a sequence of rule elements and a rule 
element essentially consists of four parts: A matching condition, an optional 
quantifier, a list of conditions and a list of actions",
+            "A");
     RutaTestUtils.assertAnnotationsEquals(cas, 7, 0);
     RutaTestUtils.assertAnnotationsEquals(cas, 8, 2, ".", ".");
     RutaTestUtils.assertAnnotationsEquals(cas, 9, 0);
     RutaTestUtils.assertAnnotationsEquals(cas, 10, 2, "A", "A");
     RutaTestUtils.assertAnnotationsEquals(cas, 11, 0);
-    RutaTestUtils
-            .assertAnnotationsEquals(
-                    cas,
-                    12,
-                    2, //
-                    "A rule is composed of a sequence of rule elements and a 
rule element essentially consists of four parts: A matching condition, an 
optional quantifier, a list of conditions and a list of actions",
-                    "The matching condition is typically a type of an 
annotation by which the rule element matches on the covered text of one of 
those annotations");
+    RutaTestUtils.assertAnnotationsEquals(cas, 12, 2, //
+            "A rule is composed of a sequence of rule elements and a rule 
element essentially consists of four parts: A matching condition, an optional 
quantifier, a list of conditions and a list of actions",
+            "The matching condition is typically a type of an annotation by 
which the rule element matches on the covered text of one of those 
annotations");
     RutaTestUtils.assertAnnotationsEquals(cas, 13, 1, ":");
     RutaTestUtils.assertAnnotationsEquals(cas, 14, 4, "A", "A", "matching", 
"matching");
+  }
 
-    cas.release();
+  @Test
+  public void testMultipleInlinedRuleBlocks() throws Exception {
+    String document ="AA 22 bb CC";
+    String script = "";
+    script += "Document{-> T1};\n";
+    // inlined as condition
+    script += "T1{-> T2} <- {CAP NUM;} <- {SW CAP;};\n";
+    // inlined as action
+    script += "T1 -> {(CAP NUM){->T3};} -> {(SW CAP){->T4};};\n";
+    
+    CAS cas = RutaTestUtils.getCAS(document);
+    Ruta.apply(cas, script);
+
+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "AA 22 bb CC");
+    RutaTestUtils.assertAnnotationsEquals(cas, 3, 1, "AA 22");
+    RutaTestUtils.assertAnnotationsEquals(cas, 4, 1, "bb CC");
   }
 }


Reply via email to