/*
* Copyright 2011 JBoss Inc
*
* Licensed 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.drools.chance.rule.constraint.core.evaluators;
import org.drools.base.ValueType;
import org.drools.base.evaluators.EvaluatorDefinition;
import org.drools.base.evaluators.Operator;
import org.drools.chance.degree.Degree;
import org.drools.chance.degree.simple.SimpleDegree;
import org.drools.chance.distribution.DiscreteDomainDistribution;
import org.drools.chance.distribution.Distribution;
import org.drools.chance.rule.builder.ChanceOperators;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.rule.VariableRestriction;
import org.drools.spi.Evaluator;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
public class HoldsEvaluatorDefinition implements EvaluatorDefinition {
public static final Operator HOLDS = Operator.addOperatorToRegistry(
"holds", false);
public static final Operator HOLDS_IMP = Operator.addOperatorToRegistry(
ChanceOperators.makeImperfect( HOLDS.getOperatorString() ), false);
public static final Operator NEG_HOLDS = Operator.addOperatorToRegistry(
"holds", true);
public static final Operator NEG_HOLDS_IMP = Operator.addOperatorToRegistry(
ChanceOperators.makeImperfect( HOLDS.getOperatorString() ), true);
private static final String[] SUPPORTED_IDS = {
HOLDS.getOperatorString(),
HOLDS_IMP.getOperatorString(),
NEG_HOLDS.getOperatorString(),
NEG_HOLDS_IMP.getOperatorString()
};
private Evaluator[] evaluator;
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, Operator operator) {
return this.getEvaluator( type, operator.getOperatorString(), operator
.isNegated(), null );
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, Operator operator,
String parameterText) {
return this.getEvaluator( type, operator.getOperatorString(), operator
.isNegated(), parameterText );
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText) {
return getEvaluator(type, operatorId, isNegated, parameterText,
Target.FACT, Target.FACT);
}
/**
* @inheridDoc
*/
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText, Target leftTarget,
Target rightTarget) {
HoldsEvaluator evaluator;
if ( parameterText != null ) {
evaluator = new HoldsEvaluator( type, isNegated, splitParams(parameterText), ChanceOperators.isImperfect(operatorId) );
} else {
evaluator = new HoldsEvaluator( type, isNegated, ChanceOperators.isImperfect(operatorId) );
}
return evaluator;
}
private List<String> splitParams( String parameterText ) {
StringTokenizer tok = new StringTokenizer( parameterText, "," );
List<String> params = new LinkedList<String>();
while ( tok.hasMoreTokens() ) {
params.add( tok.nextToken() );
}
return params;
}
/**
* @inheridDoc
*/
public String[] getEvaluatorIds() {
return SUPPORTED_IDS;
}
/**
* @inheridDoc
*/
public Target getTarget() {
return Target.FACT;
}
/**
* @inheridDoc
*/
public boolean isNegatable() {
return false;
}
/**
* @inheridDoc
*/
public boolean supportsType(ValueType type) {
return ( type.equals( ValueType.OBJECT_TYPE ) );
}
/**
* @inheridDoc
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
evaluator = (Evaluator[]) in.readObject();
}
/**
* @inheridDoc
*/
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(evaluator);
}
public static class HoldsEvaluator extends BaseImperfectEvaluator {
public HoldsEvaluator( final ValueType type, final boolean isNegated, boolean enableImperfectMode ) {
super( type, HOLDS, isNegated, enableImperfectMode );
}
public HoldsEvaluator( ValueType type, boolean negated, List<String> parameters, boolean enableImperfection ) {
super( type, HOLDS, negated, parameters, enableImperfection );
}
protected Degree matchDistributionToValue( Distribution leftDist, Object rightValue, InternalWorkingMemory workingMemory ) {
Degree deg = getBaseDegree().False();
if ( leftDist.isDiscrete() && leftDist.domainSize().intValue() == 1 ) {
DiscreteDomainDistribution discr = (DiscreteDomainDistribution) leftDist;
deg = discr.get( rightValue );
return matchValueToValue( deg, rightValue, workingMemory );
}
return deg;
}
@Override
protected Degree matchValueToValue( Object leftValue, Object rightValue, InternalWorkingMemory workingMemory ) {
Degree deg;
if ( leftValue instanceof Degree ) {
deg = (Degree) leftValue;
} else if ( leftValue instanceof Boolean ) {
deg = baseDegree.fromBoolean(((Boolean) leftValue));
} else {
throw new IllegalStateException( "Holds is a unary evaluator applicable to Degrees only ");
}
if ( negated ) {
deg = not.eval( deg );
}
return deg;
}
@Override
public String toString() {
return "HoldsEvaluatorDefinition holds";
}
}
}