You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by vm...@apache.org on 2019/01/11 15:26:47 UTC

svn commit: r1851060 - in /uima/ruta/trunk/ruta-core/src: main/antlr3/org/apache/uima/ruta/parser/ main/java/org/apache/uima/ruta/rule/ main/java/org/apache/uima/ruta/verbalize/ test/java/org/apache/uima/ruta/rule/

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");
   }
 }