summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorLester Solbakken <lesters@yahoo-inc.com>2017-11-15 15:40:00 +0100
committerLester Solbakken <lesters@yahoo-inc.com>2017-11-15 15:40:00 +0100
commit0d69ba9852d879eb5bf61962095e95cd5f3e3c7d (patch)
tree793de7797a4786a3c319c5c0f6757d21a3247291 /searchlib
parentc7c7f25a47b9debfc07a6ebbe7702d3d8ed8c476 (diff)
Add Java ranking power operator
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleCompatibleValue.java5
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/StringValue.java5
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java8
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java2
-rw-r--r--searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/ArithmeticOperator.java4
-rwxr-xr-xsearchlib/src/main/javacc/RankingExpressionParser.jj16
-rw-r--r--searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java3
7 files changed, 36 insertions, 7 deletions
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleCompatibleValue.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleCompatibleValue.java
index 0868af9bc72..ea750295423 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleCompatibleValue.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/DoubleCompatibleValue.java
@@ -59,6 +59,11 @@ public abstract class DoubleCompatibleValue extends Value {
}
@Override
+ public Value power(Value value) {
+ return new DoubleValue(Function.pow.evaluate(asDouble(), value.asDouble()));
+ }
+
+ @Override
public Value compare(TruthOperator operator, Value value) {
return new BooleanValue(operator.evaluate(asDouble(), value.asDouble()));
}
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/StringValue.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/StringValue.java
index b62081f2c6a..ac8aba6a617 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/StringValue.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/StringValue.java
@@ -88,6 +88,11 @@ public class StringValue extends Value {
}
@Override
+ public Value power(Value value) {
+ throw new UnsupportedOperationException("String values ('" + value + "') do not support ^");
+ }
+
+ @Override
public Value compare(TruthOperator operator, Value value) {
if (operator.equals(TruthOperator.EQUAL))
return new BooleanValue(this.equals(value));
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java
index 919a23eeaf5..49c3ccb7b01 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/TensorValue.java
@@ -110,6 +110,14 @@ public class TensorValue extends Value {
return new TensorValue(value.map((value) -> (value==0.0) ? 1.0 : 0.0));
}
+ @Override
+ public Value power(Value argument) {
+ if (argument instanceof TensorValue)
+ return new TensorValue(value.pow(((TensorValue)argument).value));
+ else
+ return new TensorValue(value.map((value) -> Math.pow(value, argument.asDouble())));
+ }
+
private Tensor asTensor(Value value, String operationName) {
if ( ! (value instanceof TensorValue))
throw new UnsupportedOperationException("Could not perform " + operationName +
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java
index bcbce6e646f..b2ccbe572d0 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Value.java
@@ -49,6 +49,8 @@ public abstract class Value {
public abstract Value not();
+ public abstract Value power(Value value);
+
/** Perform the comparison specified by the operator between this value and the given value */
public abstract Value compare(TruthOperator operator, Value value);
diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/ArithmeticOperator.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/ArithmeticOperator.java
index aae59fe2af8..a715490e95a 100644
--- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/ArithmeticOperator.java
+++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/rule/ArithmeticOperator.java
@@ -34,6 +34,9 @@ public enum ArithmeticOperator {
}},
MODULO(6, "%") { public Value evaluate(Value x, Value y) {
return x.modulo(y);
+ }},
+ POWER(7, "^") { public Value evaluate(Value x, Value y) {
+ return x.power(y);
}};
/** A list of all the operators in this in order of decreasing precedence */
@@ -61,6 +64,7 @@ public enum ArithmeticOperator {
private static List<ArithmeticOperator> operatorsByPrecedence() {
List<ArithmeticOperator> operators = new ArrayList<>();
+ operators.add(POWER);
operators.add(MODULO);
operators.add(DIVIDE);
operators.add(MULTIPLY);
diff --git a/searchlib/src/main/javacc/RankingExpressionParser.jj b/searchlib/src/main/javacc/RankingExpressionParser.jj
index 035a92b0365..7821ab88b86 100755
--- a/searchlib/src/main/javacc/RankingExpressionParser.jj
+++ b/searchlib/src/main/javacc/RankingExpressionParser.jj
@@ -66,6 +66,7 @@ TOKEN :
<MUL: "*"> |
<DOT: "."> |
<MOD: "%"> |
+ <POWOP: "^"> |
<DOLLAR: "$"> |
<COMMA: ","> |
@@ -204,13 +205,14 @@ ExpressionNode arithmeticExpression() :
ArithmeticOperator arithmetic() : { }
{
- ( <ADD> { return ArithmeticOperator.PLUS; } |
- <SUB> { return ArithmeticOperator.MINUS; } |
- <DIV> { return ArithmeticOperator.DIVIDE; } |
- <MUL> { return ArithmeticOperator.MULTIPLY; } |
- <MOD> { return ArithmeticOperator.MODULO; } |
- <AND> { return ArithmeticOperator.AND; } |
- <OR> { return ArithmeticOperator.OR; } )
+ ( <ADD> { return ArithmeticOperator.PLUS; } |
+ <SUB> { return ArithmeticOperator.MINUS; } |
+ <DIV> { return ArithmeticOperator.DIVIDE; } |
+ <MUL> { return ArithmeticOperator.MULTIPLY; } |
+ <MOD> { return ArithmeticOperator.MODULO; } |
+ <AND> { return ArithmeticOperator.AND; } |
+ <OR> { return ArithmeticOperator.OR; } |
+ <POWOP> { return ArithmeticOperator.POWER; } )
{ return null; }
}
diff --git a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java
index 26d3695dd07..8e34f35245d 100644
--- a/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java
+++ b/searchlib/src/test/java/com/yahoo/searchlib/rankingexpression/evaluation/EvaluationTestCase.java
@@ -29,6 +29,7 @@ public class EvaluationTestCase {
tester.assertEvaluates(0.75, "0.5 + 0.25");
tester.assertEvaluates(0.75, "one_half + a_quarter");
tester.assertEvaluates(1.25, "0.5 - 0.25 + one");
+ tester.assertEvaluates(9.0, "3 ^ 2");
// String
tester.assertEvaluates(1, "if(\"a\"==\"a\",1,0)");
@@ -38,6 +39,8 @@ public class EvaluationTestCase {
tester.assertEvaluates(1, "2/6+4/6");
tester.assertEvaluates(2 * 3 * 4 + 3 * 4 * 5 - 4 * 200 / 10, "2*3*4+3*4*5-4*200/10");
tester.assertEvaluates(3, "1 + 10 % 6 / 2");
+ tester.assertEvaluates(10.0, "3 ^ 2 + 1");
+ tester.assertEvaluates(18.0, "2 * 3 ^ 2");
// Conditionals
tester.assertEvaluates(2 * (3 * 4 + 3) * (4 * 5 - 4 * 200) / 10, "2*(3*4+3)*(4*5-4*200)/10");