blob: 38dd1c39016bbea57a77f0e3d04cbd6442ea725f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.ruta.textruler.learner.trabal;
import java.util.List;
import org.apache.uima.ruta.textruler.core.TextRulerTarget;
public class ExpansionRule extends ShiftingRule {
public ExpansionRule(TrabalLearner parentAlgorithm, TextRulerTarget target,
TrabalAnnotation annotation, TrabalAnnotation targetAnnotation,
AnnotationErrorType errorType) {
super(parentAlgorithm, target, annotation, targetAnnotation, errorType);
}
public ExpansionRule(ExpansionRule copyFrom) {
super(copyFrom);
}
@Override
public void compileRuleString() {
ruleString = "";
int errorBegin = annotation.getBegin();
int truthBegin = targetAnnotation.getBegin();
int truthEnd = targetAnnotation.getEnd();
boolean expandToLeft = truthBegin < errorBegin;
if (expandToLeft) // (frontBoundaryItem ANY*? annotation){-> MARK(targetAnnotation)};
expandToLeft(truthBegin);
else
// (annotation ANY*? rearBoundaryItem){-> MARK(targetAnnotation)};
expandToRight(truthEnd);
setNeedsCompile(false);
}
private void expandToLeft(int truthBegin) {
// should the boundary item be part of the new annotation?
boolean frontItemInBorders = frontBoundaryItem.getAnnotation().getBegin() == truthBegin;
// parse the positive conditions
String conditions = parseConditions(conditionTypes, true);
if (conditions.length() > 0)
conditions += " ";
// parse the negative conditions
conditionTypes.add(ConditionType.BEFORE);
String negativeConditions = parseConditions(conditionTypes, false);
if (negativeConditions.length() > 0)
negativeConditions += " ";
String before = parseConditions(ConditionType.BEFORE, true);
if (before.length() > 0 && negativeConditions.length() > 0)
negativeConditions = before + ", " + negativeConditions;
else if (before.length() > 0)
negativeConditions = before + " ";
// this strings will be attached to the original annotation
String unmark = "{" + negativeConditions + "-> UNMARK(" + annotation.getType().getShortName()
+ ")}";
// this string will be attached to the front boundary item
String after = parseConditions(ConditionType.AFTER);
if (after.length() > 0)
after = "{" + after + "}";
// If the front item is part of the future annotation, it has to be included in the brackets.
if (frontItemInBorders)
ruleString += "(" + frontBoundaryItem + after + " ";
else
ruleString += frontBoundaryItem + after + " (";
// We include all tokens between the boundaries.
ruleString += "ANY*{-PARTOF(" + annotation.getType().getShortName() + ")} "; // like ANY*? but
// faster
// ruleString += "#{-CONTAINS(" + annotation.getType().getShortName() + ")} ";
// these strings will be attached to the brackets
String mark;
if (((TrabalLearner) algorithm).getEnableFeatures())
mark = "-> CREATE(" + targetAnnotation.getType().getShortName() + parseFeatures() + ")";
else
mark = "-> MARK(" + targetAnnotation.getType().getShortName() + ")";
String action = "{" + conditions + mark + "}";
// The original annotation represents the rear boundary item
ruleString += annotation.getType().getShortName() + unmark + ")" + action + ";";
}
private void expandToRight(int truthEnd) {
// should the boundary items be part of the new annotation?
boolean rearItemInBorders = rearBoundaryItem.getAnnotation().getEnd() == truthEnd;
// parse the positive conditions
String conditions = parseConditions(conditionTypes, true);
if (conditions.length() > 0)
conditions += " ";
// parse the negative conditions
conditionTypes.add(ConditionType.AFTER);
String negativeConditions = parseConditions(conditionTypes, false);
if (negativeConditions.length() > 0)
negativeConditions += " ";
String after = parseConditions(ConditionType.AFTER, true);
if (after.length() > 0 && negativeConditions.length() > 0)
negativeConditions = after + ", " + negativeConditions;
else if (after.length() > 0)
negativeConditions = after + " ";
// this strings will be attached to the original annotation
String unmark = "{" + negativeConditions + "-> UNMARK(" + annotation.getType().getShortName()
+ ")}";
// The original annotation represents the front boundary item
ruleString += "(" + annotation.getType().getShortName() + unmark + " ";
// We include all tokens between the boundaries.
ruleString += "ANY*{-PARTOF(" + rearBoundaryItem + ")}"; // like ANY*? but faster
// ruleString += "#{-CONTAINS(" + rearBoundaryItem + ")}"; // like ... but faster
// these strings will be attached to the brackets
String mark;
if (((TrabalLearner) algorithm).getEnableFeatures())
mark = "-> CREATE(" + targetAnnotation.getType().getShortName() + parseFeatures() + ")";
else
mark = "-> MARK(" + targetAnnotation.getType().getShortName() + ")";
String action = "{" + conditions + mark + "}";
// this string will be attached to the rear boundary item
String before = parseConditions(ConditionType.BEFORE);
if (before.length() > 0)
before = "{" + before + "}";
// If the rear item is part of the future annotation, it has to be included in the brackets
if (rearItemInBorders)
ruleString += " " + rearBoundaryItem + before + ")" + action + ";";
else
ruleString += ")" + action + " " + rearBoundaryItem + before + ";";
}
/**
* Parse either the positive or the negative conditions without negation mark.
*
* @param types
* the types, that should be parsed
* @param positive
* true for positive, false for negative conditions
* @return String with parsed conditions
*/
private String parseConditions(List<ConditionType> types, boolean positive) {
String result = "";
for (Condition each : conditions)
if (types.contains(each.getType()) && each.isNegative() != positive)
if (each.isNegative()) {
each.changePosNegValue();
result += each + ", ";
each.changePosNegValue();
} else
result += each + ", ";
if (result.length() > 0)
return result.substring(0, result.length() - 2);
return "";
}
/**
* Parse either the positive or the negative conditions without negation mark.
*
* @param type
* the type, that should be parsed
* @param positive
* true for positive, false for negative conditions
* @return String with parsed conditions
*/
private String parseConditions(ConditionType type, boolean positive) {
String result = "";
for (Condition each : conditions)
if (each.getType() == type && each.isNegative() != positive)
if (each.isNegative()) {
each.changePosNegValue();
result += each + ", ";
each.changePosNegValue();
} else
result += each + ", ";
if (result.length() > 0)
return result.substring(0, result.length() - 2);
return "";
}
@Override
public TrabalRule copy() {
return new ExpansionRule(this);
}
}