blob: 2c9d3fc62b5372b1d5c176c48c475c43576f5b03 [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.lp2;
import java.util.ArrayList;
import java.util.List;
import org.apache.uima.cas.Type;
import org.apache.uima.ruta.textruler.core.TextRulerAnnotation;
import org.apache.uima.ruta.textruler.core.TextRulerRule;
import org.apache.uima.ruta.textruler.core.TextRulerRuleItem;
import org.apache.uima.ruta.textruler.core.TextRulerSingleSlotRule;
import org.apache.uima.ruta.textruler.core.TextRulerTarget.MLTargetType;
import org.apache.uima.ruta.textruler.core.TextRulerToolkit;
import org.apache.uima.ruta.textruler.core.TextRulerWordConstraint;
public class LP2RuleItem implements TextRulerRuleItem {
protected TextRulerWordConstraint wordConstraint;
protected MLLP2ContextConstraint contextConstraint;
protected List<MLLP2OtherConstraint> otherConstraints = new ArrayList<MLLP2OtherConstraint>();
public static class MLLP2ContextConstraint {
private String contextBoundaryName;
private int contextSize;
private boolean direction; // false = left; true = right;
public MLLP2ContextConstraint(int contextSize, LP2Rule parentRule) {
super();
this.contextSize = contextSize;
contextBoundaryName = TextRulerToolkit.getTypeShortName(parentRule.getTarget()
.getCounterPartBoundaryTarget().getSingleSlotTypeName());
direction = parentRule.getTarget().type == MLTargetType.SINGLE_LEFT_BOUNDARY ? true : false;
}
public MLLP2ContextConstraint(MLLP2ContextConstraint copyFrom) {
super();
contextBoundaryName = copyFrom.contextBoundaryName;
contextSize = copyFrom.contextSize;
direction = copyFrom.direction;
}
public MLLP2ContextConstraint copy() {
return new MLLP2ContextConstraint(this);
}
@Override
public String toString() {
return "NEAR(" + contextBoundaryName + ", 0," + contextSize + ","
+ (direction ? "true" : "false") + ",true)";
}
@Override
public boolean equals(Object o) {
return toString().equals(((MLLP2ContextConstraint) o).toString());
}
@Override
public int hashCode() {
return toString().hashCode();
}
}
public static class MLLP2OtherConstraint {
TextRulerAnnotation tokenAnnotation;
TextRulerAnnotation constraintAnnotation;
boolean canBeAnchor;
Type type;
public MLLP2OtherConstraint(TextRulerAnnotation tokenAnnotation,
TextRulerAnnotation constraintAnnotation) {
this.tokenAnnotation = tokenAnnotation;
this.constraintAnnotation = constraintAnnotation;
this.type = constraintAnnotation.getType();
canBeAnchor = (tokenAnnotation.getBegin() == constraintAnnotation.getBegin())
&& (tokenAnnotation.getEnd() == constraintAnnotation.getEnd());
// TODO is the matching END also a requirement ?
}
public boolean isTMBasicTypeTokenConstraint() {
return tokenAnnotation == constraintAnnotation;
}
public boolean canBeAnchorConstraint() {
return canBeAnchor;
}
@Override
public boolean equals(Object o) {
MLLP2OtherConstraint co = (MLLP2OtherConstraint) o;
return toString().equals(co.toString()) && (canBeAnchor == co.canBeAnchor);
}
@Override
public int hashCode() {
return toString().hashCode() * (canBeAnchor ? 2 : 1);
}
@Override
public String toString() {
return type.getShortName();
}
public MLLP2OtherConstraint copy() {
return new MLLP2OtherConstraint(tokenAnnotation, constraintAnnotation);
}
}
public LP2RuleItem(LP2RuleItem copyFrom) {
super();
if (copyFrom.wordConstraint != null)
wordConstraint = copyFrom.wordConstraint.copy();
if (copyFrom.contextConstraint != null)
contextConstraint = copyFrom.contextConstraint.copy();
for (MLLP2OtherConstraint c : copyFrom.otherConstraints)
otherConstraints.add(c.copy());
}
public LP2RuleItem() {
super();
}
public LP2RuleItem copy() {
return new LP2RuleItem(this);
}
@Override
public int hashCode() {
return toString().hashCode();
}
public boolean equals(TextRulerRuleItem o) {
return toString().equals(((LP2RuleItem) o).toString());
}
@Override
public String toString() {
return getStringForRuleString(null, null, 0, 0, 0, 0, 0);
}
public MLLP2OtherConstraint getTMBasicTypeTokenConstraint() {
for (MLLP2OtherConstraint c : otherConstraints)
if (c.isTMBasicTypeTokenConstraint())
return c;
return null;
}
public String getStringForRuleString(TextRulerRule rule, MLRuleItemType type,
int numberInPattern, int patternSize, int numberInRule, int ruleSize, int slotIndex) {
String result = "";
LP2Rule lp2Rule = (LP2Rule) rule;
boolean isMarkingItem = (rule != null)
&& (((rule.getTarget().type == MLTargetType.SINGLE_RIGHT_BOUNDARY)
&& (type == MLRuleItemType.PREFILLER) && (numberInPattern == patternSize - 1)) || ((rule
.getTarget().type == MLTargetType.SINGLE_LEFT_BOUNDARY)
&& (type == MLRuleItemType.POSTFILLER) && (numberInPattern == 0)));
ArrayList<String> constraints = new ArrayList<String>();
String anchor = null;
if (wordConstraint == null)
anchor = "ANY";
else {
if (wordConstraint.isRegExpConstraint()) {
anchor = wordConstraint.typeShortName();
constraints.add("REGEXP(\"" + wordConstraint + "\")");
} else
anchor = wordConstraint.toString();
}
if (isMarkingItem && lp2Rule.isContextualRule())
constraints.add("-IS(" + ((TextRulerSingleSlotRule) rule).getMarkName() + ")");
if (contextConstraint != null)
constraints.add(contextConstraint.toString());
MLLP2OtherConstraint anchorConstraint = null;
if (wordConstraint == null) {
// prefer the basic Ruta constraint as the anchor
anchorConstraint = getTMBasicTypeTokenConstraint(); // returns null
// if we don't
// have one...
if (anchorConstraint == null) {
for (MLLP2OtherConstraint c : otherConstraints)
if (c.canBeAnchorConstraint()) {
anchorConstraint = c;
break;
}
}
for (MLLP2OtherConstraint oc : otherConstraints) {
if (oc != anchorConstraint) {
if (oc.canBeAnchorConstraint())
constraints.add("IS(" + oc + ")");
else
constraints.add("PARTOF(" + oc + ")");
}
}
if (anchorConstraint != null)
anchor = anchorConstraint.toString();
}
if (constraints.size() > 0) {
String cStr = "";
for (String constraintStr : constraints) {
if (cStr.length() > 0)
cStr += ", ";
cStr += constraintStr;
}
result += "{" + cStr;
}
if ((rule != null)
&& (((rule.getTarget().type == MLTargetType.SINGLE_RIGHT_BOUNDARY)
&& (type == MLRuleItemType.PREFILLER) && (numberInPattern == patternSize - 1)) || ((rule
.getTarget().type == MLTargetType.SINGLE_LEFT_BOUNDARY)
&& (type == MLRuleItemType.POSTFILLER) && (numberInPattern == 0)))) {
// result +=
// "(MARKONCE, "+((TextRulerSingleSlotRule)rule).getMarkName()+", "+(numberInRule+1);
if (constraints.size() == 0)
result += "{";
result += "->MARKONCE(" + ((TextRulerSingleSlotRule) rule).getMarkName() + ")";
if (lp2Rule.isContextualRule())
result += ", ASSIGN(redoContextualRules, true)";
result += "}";
} else {
if (constraints.size() != 0)
result += "}";
}
return anchor + result;
}
public void addOtherConstraint(MLLP2OtherConstraint c) {
if (!otherConstraints.contains(c))
otherConstraints.add(c);
}
public List<MLLP2OtherConstraint> getOtherConstraints() {
return otherConstraints;
}
public void setWordConstraint(TextRulerAnnotation tokenAnnotation) {
setWordConstraint(new TextRulerWordConstraint(tokenAnnotation));
}
public void setContextConstraint(MLLP2ContextConstraint c) {
contextConstraint = c;
}
public MLLP2ContextConstraint getContextConstraint() {
return contextConstraint;
}
public void setWordConstraint(TextRulerWordConstraint c) {
wordConstraint = c;
}
public TextRulerWordConstraint getWordConstraint() {
return wordConstraint;
}
public int totalConstraintCount() {
return otherConstraints.size() + (wordConstraint != null ? 1 : 0)
+ (contextConstraint != null ? 1 : 0);
}
}