This is an automated email from the ASF dual-hosted git repository.

gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new f2669bf41b [Incubator kie issues#2173] Decouple FEELDialect from 
BooleanEvalHelper (#6537)
f2669bf41b is described below

commit f2669bf41b22e91457e34ec4581705eb0918ebeb
Author: ChinchuAjith <[email protected]>
AuthorDate: Fri Dec 5 16:31:31 2025 +0530

    [Incubator kie issues#2173] Decouple FEELDialect from BooleanEvalHelper 
(#6537)
    
    * [incubator-kie-issues#2099] Fixed BFEEL execution
    
    * [incubator-kie-issues#2099] Missing header
    
    * [incubator-kie-issues#2099] Fixed date+number case
    
    * AddExecutor : Design and Implementation
    
    * AddExecutor : Design and Implementation - Review comments fix
    
    * AndExecutor : Design and Implementation
    
    * Gte, Gt and Eq executors implementation
    
    * Lte, Lt, NotEqual, Or and Pow executors implementation
    
    * Code cleanup - executor classes
    
    * Code cleanup, adding comments
    
    * Adding license headers and removing commented code
    
    * Correcting minor comments
    
    * Review comments fix
    
    * Fixing AND operator short cut scenario
    
    * Removing unused imports
    
    * Code Formatting, review comments
    
    * Removing Feel dialect dependency from the Util class
    
    * Code clean up
    
    * Fixing Review comments
    
    * Resolving test failures
    
    * Removing commented lines
    
    * Removing commented lines
    
    ---------
    
    Co-authored-by: Gabriele-Cardosi <[email protected]>
---
 .../org/kie/dmn/feel/lang/ast/BetweenNode.java     |  21 +-
 .../dmn/feel/lang/ast/FunctionInvocationNode.java  |  25 +-
 .../java/org/kie/dmn/feel/lang/ast/InNode.java     |  37 +--
 .../org/kie/dmn/feel/lang/ast/UnaryTestNode.java   | 165 ++++++------
 .../ast/dialectHandlers/BFEELDialectHandler.java   | 229 ++++++++++++++--
 .../ast/dialectHandlers/DefaultDialectHandler.java | 295 ++++++++++++++++-----
 .../ast/dialectHandlers/FEELDialectHandler.java    | 139 +++++++++-
 .../main/java/org/kie/dmn/feel/runtime/Range.java  |  13 +-
 .../runtime/functions/DecisionTableFunction.java   | 138 +++++-----
 .../kie/dmn/feel/runtime/functions/IsFunction.java |   9 +-
 .../org/kie/dmn/feel/runtime/impl/RangeImpl.java   |  86 +++---
 .../org/kie/dmn/feel/util/BooleanEvalHelper.java   | 161 +----------
 .../org/kie/dmn/feel/util/DateTimeEvalHelper.java  |  18 +-
 .../kie/dmn/feel/runtime/impl/RangeImplTest.java   |  63 ++---
 .../kie/dmn/feel/util/BooleanEvalHelperTest.java   |  59 ++---
 .../dmn/validation/dtanalysis/model/Interval.java  |  97 ++++---
 16 files changed, 931 insertions(+), 624 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BetweenNode.java 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BetweenNode.java
index 430ff574ac..0ac663c89c 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BetweenNode.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/BetweenNode.java
@@ -24,9 +24,10 @@ import 
org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity;
 import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.FEELDialect;
 import org.kie.dmn.feel.lang.Type;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandler;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandlerFactory;
 import org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils;
 import org.kie.dmn.feel.lang.types.BuiltInType;
-import org.kie.dmn.feel.util.BooleanEvalHelper;
 import org.kie.dmn.feel.util.Msg;
 
 public class BetweenNode
@@ -89,7 +90,8 @@ public class BetweenNode
             ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.IS_NULL, "end")));
             problem = true;
         }
-        if (problem) return null;
+        if (problem)
+            return null;
 
         Object o_val = value.evaluate(ctx);
         Object o_s = start.evaluate(ctx);
@@ -107,22 +109,19 @@ public class BetweenNode
             ctx.notifyEvt(astEvent(severity, Msg.createMessage(Msg.IS_NULL, 
"end")));
             problem = true;
         }
-        if (problem && ctx.getFEELDialect() != FEELDialect.BFEEL) return null;
+        if (problem && ctx.getFEELDialect() != FEELDialect.BFEEL)
+            return null;
 
-        Object gte = InfixExecutorUtils.or(BooleanEvalHelper.compare(o_val, 
o_s, ctx.getFEELDialect(), (l, r) -> l.compareTo(r) > 0),
-                                           BooleanEvalHelper.isEqual(o_val, 
o_s, ctx.getFEELDialect()),
-                                           ctx); // do not use Java || to 
avoid potential NPE due to FEEL 3vl.
+        DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
+        Object gte = handler.executeGte(o_val, o_s, ctx);
         if (gte == null) {
             ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "value", "start")));
         }
 
-        Object lte = InfixExecutorUtils.or(BooleanEvalHelper.compare(o_val, 
o_e, ctx.getFEELDialect(), (l, r) -> l.compareTo(r) < 0),
-                BooleanEvalHelper.isEqual(o_val, o_e, ctx.getFEELDialect()),
-                ctx); // do not use Java || to avoid potential NPE due to FEEL 
3vl.
+        Object lte = handler.executeLte(o_val, o_e, ctx);
         if (lte == null) {
             ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "value", "end")));
         }
-
         return InfixExecutorUtils.and(gte, lte, ctx); // do not use Java && to 
avoid potential NPE due to FEEL 3vl.
     }
 
@@ -133,7 +132,7 @@ public class BetweenNode
 
     @Override
     public ASTNode[] getChildrenNode() {
-        return new ASTNode[]{value, start, end};
+        return new ASTNode[] { value, start, end };
     }
 
     @Override
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/FunctionInvocationNode.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/FunctionInvocationNode.java
index 411037473c..d910e4c5a2 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/FunctionInvocationNode.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/FunctionInvocationNode.java
@@ -37,13 +37,12 @@ import org.kie.dmn.feel.util.MsgUtil;
 public class FunctionInvocationNode
         extends BaseNode {
 
-
     private BaseNode name;
     private ListNode params;
     private TemporalConstantNode tcFolded; // this is NOT a child node 
intentionally.
 
     public FunctionInvocationNode(ParserRuleContext ctx, BaseNode name, 
ListNode params) {
-        super( ctx );
+        super(ctx);
         this.name = name;
         this.params = params;
     }
@@ -86,22 +85,22 @@ public class FunctionInvocationNode
         }
         FEELFunction function;
         Object value;
-        if ( name instanceof NameRefNode ) {
+        if (name instanceof NameRefNode) {
             // simple name
-            value = ctx.getValue( name.getText() );
+            value = ctx.getValue(name.getText());
         } else if (name instanceof QualifiedNameNode) {
             QualifiedNameNode qn = (QualifiedNameNode) name;
             String[] qns = qn.getPartsAsStringArray();
-            value = ctx.getValue( qns );
+            value = ctx.getValue(qns);
         } else if (name instanceof PathExpressionNode) {
             PathExpressionNode pathExpressionNode = (PathExpressionNode) name;
             value = pathExpressionNode.evaluate(ctx);
         } else {
             value = name.evaluate(ctx);
         }
-        if ( value instanceof FEELFunction ) {
+        if (value instanceof FEELFunction) {
             function = (FEELFunction) value;
-            Object[] p = params.getElements().stream().map( e -> e.evaluate( 
ctx ) ).toArray( Object[]::new );
+            Object[] p = params.getElements().stream().map(e -> 
e.evaluate(ctx)).toArray(Object[]::new);
             List<String> functionNameParts;
             if (name instanceof NameRefNode) {
                 functionNameParts = Collections.singletonList(name.getText());
@@ -114,17 +113,17 @@ public class FunctionInvocationNode
             }
             Object result = invokeTheFunction(functionNameParts, function, 
ctx, p);
             return result;
-        } else if( value instanceof UnaryTest ) {
-            if( params.getElements().size() == 1 ) {
-                Object p = params.getElements().get( 0 ).evaluate( ctx );
-                return ((UnaryTest) value).apply( ctx, p );
+        } else if (value instanceof UnaryTest) {
+            if (params.getElements().size() == 1) {
+                Object p = params.getElements().get(0).evaluate(ctx);
+                return ((UnaryTest) value).apply(ctx, p);
             } else {
-                ctx.notifyEvt( astEvent(Severity.ERROR, 
Msg.createMessage(Msg.CAN_T_INVOKE_AN_UNARY_TEST_WITH_S_PARAMETERS_UNARY_TESTS_REQUIRE_1_SINGLE_PARAMETER,
 params.getElements().size()) ) );
+                ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.CAN_T_INVOKE_AN_UNARY_TEST_WITH_S_PARAMETERS_UNARY_TESTS_REQUIRE_1_SINGLE_PARAMETER,
 params.getElements().size())));
             }
         } else if (value instanceof Range) {
             if (params.getElements().size() == 1) {
                 Object p = params.getElements().get(0).evaluate(ctx);
-                return ((Range) value).includes(ctx.getFEELDialect(), p);
+                return ((Range) value).includes(ctx, p);
             } else {
                 ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.CAN_T_INVOKE_AN_UNARY_TEST_WITH_S_PARAMETERS_UNARY_TESTS_REQUIRE_1_SINGLE_PARAMETER,
 params.getElements().size())));
             }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/InNode.java 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/InNode.java
index 1486d3161d..a8e7bc2813 100644
--- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/InNode.java
+++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/InNode.java
@@ -35,7 +35,7 @@ public class InNode
     private BaseNode exprs;
 
     public InNode(ParserRuleContext ctx, BaseNode value, BaseNode exprs) {
-        super( ctx );
+        super(ctx);
         this.value = value;
         this.exprs = exprs;
     }
@@ -64,42 +64,43 @@ public class InNode
 
     @Override
     public Boolean evaluate(EvaluationContext ctx) {
-        if (exprs == null) return null;
-        Object value = this.value.evaluate( ctx );
-        Object expr = this.exprs.evaluate( ctx );
-        if ( expr != null ) {
-            if ( expr instanceof Iterable ) {
+        if (exprs == null)
+            return null;
+        Object value = this.value.evaluate(ctx);
+        Object expr = this.exprs.evaluate(ctx);
+        if (expr != null) {
+            if (expr instanceof Iterable) {
                 // evaluate in the collection
-                for ( Object e : ((Iterable) expr) ) {
+                for (Object e : ((Iterable) expr)) {
                     // have to compare to Boolean.TRUE because in() might 
return null
-                    if ( in( ctx, value, e ) == Boolean.TRUE ) {
+                    if (in(ctx, value, e) == Boolean.TRUE) {
                         return true;
                     }
                 }
                 return false;
             } else {
                 // evaluate single entity
-                return in( ctx, value, expr );
+                return in(ctx, value, expr);
             }
         }
-        ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.IS_NULL, 
"Expression")) );
+        ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.IS_NULL, 
"Expression")));
         return null;
     }
 
     private Boolean in(EvaluationContext ctx, Object value, Object expr) {
         // need to improve this to work with unary tests
-        if ( expr == null ) {
+        if (expr == null) {
             return value == expr;
-        } else if ( expr instanceof UnaryTest ) {
-            return ((UnaryTest) expr).apply( ctx, value );
-        } else if ( expr instanceof Range ) {
+        } else if (expr instanceof UnaryTest) {
+            return ((UnaryTest) expr).apply(ctx, value);
+        } else if (expr instanceof Range) {
             try {
-                return ((Range) expr).includes(ctx.getFEELDialect(), value );
-            } catch ( Exception e ) {
-                ctx.notifyEvt( astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, 
value.toString(), expr.toString() ), e ) );
+                return ((Range) expr).includes(ctx, value);
+            } catch (Exception e) {
+                ctx.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, 
value.toString(), expr.toString()), e));
                 return null;
             }
-        } else if ( value != null ) {
+        } else if (value != null) {
             return BooleanEvalHelper.isEqualsStringCompare(value, expr);
         } else {
             // value == null, expr != null
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/UnaryTestNode.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/UnaryTestNode.java
index dc1a0262b4..914e1353b1 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/UnaryTestNode.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/UnaryTestNode.java
@@ -20,34 +20,34 @@ package org.kie.dmn.feel.lang.ast;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.function.BiPredicate;
 
 import org.antlr.v4.runtime.ParserRuleContext;
 import org.kie.dmn.api.feel.runtime.events.FEELEvent.Severity;
 import org.kie.dmn.feel.lang.EvaluationContext;
-import org.kie.dmn.feel.lang.FEELDialect;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DefaultDialectHandler;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandler;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandlerFactory;
 import org.kie.dmn.feel.runtime.Range;
 import org.kie.dmn.feel.runtime.UnaryTest;
 import org.kie.dmn.feel.runtime.UnaryTestImpl;
-import org.kie.dmn.feel.util.BooleanEvalHelper;
 import org.kie.dmn.feel.util.Msg;
 
 public class UnaryTestNode
         extends BaseNode {
 
     private UnaryOperator operator;
-    private BaseNode      value;
+    private BaseNode value;
 
     public enum UnaryOperator {
-        LTE( "<=" ),
-        LT( "<" ),
-        GT( ">" ),
-        GTE( ">=" ),
-        NE( "!=" ),
-        EQ( "=" ),
-        NOT( "not" ),
-        IN( "in" ),
-        TEST( "test");
+        LTE("<="),
+        LT("<"),
+        GT(">"),
+        GTE(">="),
+        NE("!="),
+        EQ("="),
+        NOT("not"),
+        IN("in"),
+        TEST("test");
 
         public final String symbol;
 
@@ -56,39 +56,39 @@ public class UnaryTestNode
         }
 
         public static UnaryOperator determineOperator(String symbol) {
-            for ( UnaryOperator op : UnaryOperator.values() ) {
-                if ( op.symbol.equals( symbol ) ) {
+            for (UnaryOperator op : UnaryOperator.values()) {
+                if (op.symbol.equals(symbol)) {
                     return op;
                 }
             }
-            throw new IllegalArgumentException( "No operator found for symbol 
'" + symbol + "'" );
+            throw new IllegalArgumentException("No operator found for symbol 
'" + symbol + "'");
         }
     }
 
-    public UnaryTestNode( String op, BaseNode value ) {
+    public UnaryTestNode(String op, BaseNode value) {
         super();
-        setText( op+" "+value.getText() );
-        this.operator = UnaryOperator.determineOperator( op );
+        setText(op + " " + value.getText());
+        this.operator = UnaryOperator.determineOperator(op);
         this.value = value;
     }
 
-    public UnaryTestNode( UnaryOperator op, BaseNode value ) {
+    public UnaryTestNode(UnaryOperator op, BaseNode value) {
         super();
-        setText( op.symbol+" "+value.getText() );
+        setText(op.symbol + " " + value.getText());
         this.operator = op;
         this.value = value;
     }
 
     public UnaryTestNode(ParserRuleContext ctx, String op, BaseNode value) {
-        super( ctx );
-        this.operator = UnaryOperator.determineOperator( op );
+        super(ctx);
+        this.operator = UnaryOperator.determineOperator(op);
         this.value = value;
     }
 
-    public UnaryTestNode( UnaryOperator op, BaseNode value, String text ) {
+    public UnaryTestNode(UnaryOperator op, BaseNode value, String text) {
         this.operator = op;
         this.value = value;
-        this.setText( text);
+        this.setText(text);
     }
 
     public UnaryOperator getOperator() {
@@ -117,35 +117,41 @@ public class UnaryTestNode
     }
 
     public UnaryTest getUnaryTest() {
-        switch ( operator ) {
-            case LTE:
-                return new UnaryTestImpl( createCompareUnaryTest( (l, r) -> 
l.compareTo( r ) <= 0 ) , value.getText() );
-            case LT:
-                return new UnaryTestImpl( createCompareUnaryTest( (l, r) -> 
l.compareTo( r ) < 0 ) , value.getText() );
-            case GT:
-                return new UnaryTestImpl( createCompareUnaryTest( (l, r) -> 
l.compareTo( r ) > 0 ) , value.getText() );
-            case GTE:
-                return new UnaryTestImpl( createCompareUnaryTest( (l, r) -> 
l.compareTo( r ) >= 0 ) , value.getText() );
-            case EQ:
-                return new UnaryTestImpl( createIsEqualUnaryTest( ) , 
value.getText() );
-            case NE:
-                return new UnaryTestImpl( createIsNotEqualUnaryTest( ) , 
value.getText() );
-            case IN:
-                return new UnaryTestImpl( createInUnaryTest() , 
value.getText() );
-            case NOT:
-                return new UnaryTestImpl( createNotUnaryTest() , 
value.getText() );
-            case TEST:
-                return new UnaryTestImpl( createBooleanUnaryTest(), 
value.getText() );
-        }
-        return null;
-    }
+        return new UnaryTestImpl((context, left) -> {
+            Object right = value.evaluate(context);
+            DialectHandler handler = DialectHandlerFactory.getHandler(context);
 
-    private UnaryTest createCompareUnaryTest( BiPredicate<Comparable, 
Comparable> op ) {
-        return (context, left) -> {
-            Object right = value.evaluate( context );
-            // Defaulting FEELDialect to FEEL
-            return BooleanEvalHelper.compare(left, right, FEELDialect.FEEL, op 
);
-        };
+            Object result;
+            switch (operator) {
+                case LTE:
+                    result = handler.executeLte(left, right, context);
+                    break;
+                case LT:
+                    result = handler.executeLt(left, right, context);
+                    break;
+                case GT:
+                    result = handler.executeGt(left, right, context);
+                    break;
+                case GTE:
+                    result = handler.executeGte(left, right, context);
+                    break;
+                case EQ:
+                    return createIsEqualUnaryTest().apply(context, left);
+                case NE:
+                    return createIsNotEqualUnaryTest().apply(context, left);
+                case IN:
+                    return createInUnaryTest().apply(context, left);
+                case NOT:
+                    return createNotUnaryTest().apply(context, left);
+                case TEST:
+                    return createBooleanUnaryTest().apply(context, left);
+
+                default:
+                    throw new UnsupportedOperationException("Unsupported 
operator: " + operator);
+            }
+
+            return (result instanceof Boolean) ? (Boolean) result : 
Boolean.FALSE;
+        }, value.getText());
     }
 
     /**
@@ -158,22 +164,23 @@ public class UnaryTestNode
             return ((Collection) right).contains(left);
         } else {
             // evaluate single entity
-            return BooleanEvalHelper.isEqual(left, right, FEELDialect.FEEL);
+            return DefaultDialectHandler.isEqual(left, right, () -> (left == 
null && right == null), () -> Boolean.FALSE);
+
         }
     }
 
-    private UnaryTest createIsEqualUnaryTest( ) {
+    private UnaryTest createIsEqualUnaryTest() {
         return (context, left) -> {
-            Object right = value.evaluate( context );
+            Object right = value.evaluate(context);
             return utEqualSemantic(left, right);
         };
     }
 
-    private UnaryTest createIsNotEqualUnaryTest( ) {
+    private UnaryTest createIsNotEqualUnaryTest() {
         return (context, left) -> {
-            Object right = value.evaluate( context );
+            Object right = value.evaluate(context);
             Boolean result = utEqualSemantic(left, right);
-            return result != null ? ! result : null;
+            return result != null ? !result : null;
         };
     }
 
@@ -182,10 +189,10 @@ public class UnaryTestNode
             if (o == null) {
                 return false;
             }
-            Object val = value.evaluate( c );
+            Object val = value.evaluate(c);
             if (val instanceof Range) {
                 try {
-                    return ((Range) val).includes(c.getFEELDialect(), o);
+                    return ((Range) val).includes(c, o);
                 } catch (Exception e) {
                     c.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, o, 
val)));
                     throw e;
@@ -200,38 +207,38 @@ public class UnaryTestNode
 
     private UnaryTest createNotUnaryTest() {
         return (c, o) -> {
-            Object val = value.evaluate( c );
-            if( val == null ) {
+            Object val = value.evaluate(c);
+            if (val == null) {
                 return null;
             }
             List<Object> tests = (List<Object>) val;
-            for( Object test : tests ) {
-                if( test == null ) {
-                    if( o == null ) {
+            for (Object test : tests) {
+                if (test == null) {
+                    if (o == null) {
                         return false;
                     }
-                } else if( test instanceof UnaryTest ) {
-                    if( ((UnaryTest)test).apply( c, o ) ) {
+                } else if (test instanceof UnaryTest) {
+                    if (((UnaryTest) test).apply(c, o)) {
                         return false;
                     }
-                } else if( o == null ) {
-                    if( test == null ) {
+                } else if (o == null) {
+                    if (test == null) {
                         return false;
                     }
-                } else if( test instanceof Range ) {
+                } else if (test instanceof Range) {
                     try {
-                        if( ((Range)test).includes(c.getFEELDialect(), o ) ) {
+                        if (((Range) test).includes(c, o)) {
                             return false;
                         }
-                    } catch ( Exception e ) {
-                        c.notifyEvt( astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, o, test 
) ) );
+                    } catch (Exception e) {
+                        c.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, o, 
test)));
                         throw e;
                     }
                 } else if (test instanceof Collection) {
                     return !((Collection) test).contains(o);
                 } else {
                     // test is a constant, so return false if it is equal to 
"o"
-                    if( test.equals( o ) ) {
+                    if (test.equals(o)) {
                         return false;
                     }
                 }
@@ -240,13 +247,13 @@ public class UnaryTestNode
         };
     }
 
-    private UnaryTest createBooleanUnaryTest( ) {
+    private UnaryTest createBooleanUnaryTest() {
         return (context, left) -> {
-            Object right = value.evaluate( context );
-            if( right instanceof Boolean ) {
+            Object right = value.evaluate(context);
+            if (right instanceof Boolean) {
                 return (Boolean) right;
             } else {
-                context.notifyEvt( astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXTENDED_UNARY_TEST_MUST_BE_BOOLEAN, value.getText(), 
right ) ) );
+                context.notifyEvt(astEvent(Severity.ERROR, 
Msg.createMessage(Msg.EXTENDED_UNARY_TEST_MUST_BE_BOOLEAN, value.getText(), 
right)));
                 return Boolean.FALSE;
             }
         };
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
index 9f15fe194c..251d578f3d 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
@@ -24,12 +24,13 @@ import java.time.LocalDate;
 import java.time.chrono.ChronoPeriod;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.BiFunction;
 
 import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.FEELDialect;
+import org.kie.dmn.feel.lang.ast.infixexecutors.EqExecutor;
 import org.kie.dmn.feel.lang.types.impl.ComparablePeriod;
-import org.kie.dmn.feel.util.BooleanEvalHelper;
 
 import static 
org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.getString;
 
@@ -84,67 +85,245 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getAndOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
         FEELDialect dialect = ctx.getFEELDialect();
+
         // Special case: true AND otherwise → false
         map.put(
                 new CheckedPredicate((left, right) -> {
-                    Boolean leftBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect);
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
                     Object rightValue = evalRight(right, ctx);
-                    Boolean rightBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(rightValue, dialect);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
                     return Boolean.TRUE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
                 }, false),
                 (left, right) -> Boolean.FALSE);
 
-        // Special case: otherwise AND true → false
+        // Special case: false AND true → false
         map.put(
                 new CheckedPredicate((left, right) -> {
-                    Boolean leftBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect);
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
                     Object rightValue = evalRight(right, ctx);
-                    Boolean rightBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(rightValue, dialect);
-                    return leftBool == null && Boolean.TRUE.equals(rightBool);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.TRUE.equals(rightBool);
                 }, false),
                 (left, right) -> Boolean.FALSE);
 
-        // Special case: otherwise AND otherwise → false
+        // Special case: false AND false → false
         map.put(
                 new CheckedPredicate((left, right) -> {
-                    Boolean leftBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect);
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
                     Object rightValue = evalRight(right, ctx);
-                    Boolean rightBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(rightValue, dialect);
-                    return leftBool == null && Boolean.FALSE.equals(rightBool);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
                 }, false),
                 (left, right) -> Boolean.FALSE);
+
         map.putAll(getCommonAndOperations(ctx));
         return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getEqualOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonEqualOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // Shortcut: null = null → false
+        map.put(
+                new CheckedPredicate((left, right) -> left == null && right == 
null, false),
+                (left, right) -> Boolean.TRUE);
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> isEqual(left, right,
+                        () -> Boolean.FALSE, () -> Boolean.FALSE));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getGteOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonGteOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+        // Any non-Boolean coerces to false, so (false,false) --> false
+        map.put(
+                new CheckedPredicate((left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Object rightValue = evalRight(right, ctx);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
+                }, false),
+                (left, right) -> Boolean.FALSE);
+
+        // non-Boolean coercion to false
+        map.put(
+                new CheckedPredicate((left, right) -> (!(left instanceof 
Boolean) || !(right instanceof Boolean)), false),
+                (left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Boolean rightBool = (right instanceof Boolean) ? (Boolean) 
right : Boolean.FALSE;
+                    return leftBool || rightBool;
+                });
+        // numeric/comparable >= logic
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean greater = compare(left, right, (l, r) -> 
l.compareTo(r) > 0,
+                            () -> Boolean.FALSE,
+                            () -> Boolean.FALSE);
+                    //Boolean equal = BooleanEvalHelper.isEqual(left, right, 
ctx.getFEELDialect());
+                    Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
+                            ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
+                            : null;
+
+                    if (greater == null && equal == null) {
+                        return Boolean.FALSE; // BFEEL default
+                    }
+                    if (Boolean.TRUE.equals(greater) || 
Boolean.TRUE.equals(equal)) {
+                        return Boolean.TRUE;
+                    }
+                    return Boolean.FALSE;
+                });
+
+        // Fall back to common >= operations for all other cases
+        map.putAll(getCommonGteOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getGtOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonGtOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // Any non-Boolean coerces to false, so (false,false) --> false
+        map.put(
+                new CheckedPredicate((left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Object rightValue = evalRight(right, ctx);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
+                }, false),
+                (left, right) -> Boolean.FALSE);
+
+        // non-Boolean coercion to false
+        map.put(
+                new CheckedPredicate((left, right) -> (!(left instanceof 
Boolean) || !(right instanceof Boolean)), false),
+                (left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Boolean rightBool = (right instanceof Boolean) ? (Boolean) 
right : Boolean.FALSE;
+                    return leftBool || rightBool;
+                });
+
+        // numeric/comparable > logic
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean greater = compare(left, right,
+                            (l, r) -> l.compareTo(r) > 0,
+                            () -> Boolean.FALSE,
+                            () -> Boolean.FALSE);
+                    return Objects.requireNonNullElse(greater, Boolean.FALSE);
+                });
+
+        map.putAll(getCommonGtOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getLteOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonLteOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // Any non-Boolean coerces to false, so (false,false) --> false
+        map.put(
+                new CheckedPredicate((left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Object rightValue = evalRight(right, ctx);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
+                }, false),
+                (left, right) -> Boolean.FALSE);
+
+        // General non-Boolean coercion to false
+        map.put(
+                new CheckedPredicate((left, right) -> (!(left instanceof 
Boolean) || !(right instanceof Boolean)), false),
+                (left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Boolean rightBool = (right instanceof Boolean) ? (Boolean) 
right : Boolean.FALSE;
+                    return leftBool || rightBool;
+                });
+
+        // Numeric/comparable ≤ logic
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean less = compare(left, right,
+                            (l, r) -> l.compareTo(r) < 0,
+                            () -> Boolean.FALSE,
+                            () -> Boolean.FALSE);
+                    Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
+                            ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
+                            : null;
+
+                    if (less == null && equal == null) {
+                        return Boolean.FALSE; // BFEEL default
+                    }
+                    if (Boolean.TRUE.equals(less) || 
Boolean.TRUE.equals(equal)) {
+                        return Boolean.TRUE;
+                    }
+                    return Boolean.FALSE;
+                });
+
+        map.putAll(getCommonLteOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getLtOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonLtOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // Non-Boolean coerces to false, so (false,false) --> false
+        map.put(
+                new CheckedPredicate((left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Object rightValue = evalRight(right, ctx);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
+                    return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
+                }, false),
+                (left, right) -> Boolean.FALSE);
+
+        // General non-Boolean coercion to false
+        map.put(
+                new CheckedPredicate((left, right) -> (!(left instanceof 
Boolean) || !(right instanceof Boolean)), false),
+                (left, right) -> {
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
+                    Boolean rightBool = (right instanceof Boolean) ? (Boolean) 
right : Boolean.FALSE;
+                    return leftBool || rightBool;
+                });
+
+        // Numeric/comparable < logic
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean less = compare(left, right,
+                            (l, r) -> l.compareTo(r) < 0,
+                            () -> Boolean.FALSE,
+                            () -> Boolean.FALSE);
+                    return Objects.requireNonNullElse(less, Boolean.FALSE);
+                });
+        map.putAll(getCommonLtOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getNotEqualOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonNotEqualOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+        // Shortcut: null != null → true
+        map.put(
+                new CheckedPredicate((left, right) -> left == null && right == 
null, false),
+                (left, right) -> Boolean.FALSE);
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean result = isEqual(left, right,
+                            () -> Boolean.FALSE, // nullFallback
+                            () -> Boolean.FALSE // defaultFallback
+                    );
+                    // If result is null, treat as false
+                    return result != null ? !result : Boolean.FALSE;
+                });
+
+        return map;
     }
 
     /**
@@ -156,18 +335,16 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getOrOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
-
-        // Special case: false OR null/otherwise → false (BFEEL override)
+        // false OR otherwise → false
         map.put(
                 new CheckedPredicate((left, right) -> {
-                    Boolean leftBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect);
+                    Boolean leftBool = (left instanceof Boolean) ? (Boolean) 
left : Boolean.FALSE;
                     Object rightValue = evalRight(right, ctx);
-                    Boolean rightBool = 
BooleanEvalHelper.getBooleanOrDialectDefault(rightValue, dialect);
+                    Boolean rightBool = (rightValue instanceof Boolean) ? 
(Boolean) rightValue : Boolean.FALSE;
                     return Boolean.FALSE.equals(leftBool) && 
Boolean.FALSE.equals(rightBool);
                 }, false),
                 (left, right) -> Boolean.FALSE);
-        // Fall back to FEEL semantics for all other cases
+
         map.putAll(getCommonOrOperations(ctx));
         return map;
     }
@@ -199,7 +376,7 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getSubOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        //subtraction with Strings → empty string
+        // empty string
         map.put(
                 new CheckedPredicate((left, right) -> (left instanceof String 
|| right instanceof String), false),
                 (left, right) -> "");
@@ -235,12 +412,12 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
                 new CheckedPredicate((left, right) -> left == null && right 
instanceof Duration, false),
                 (left, right) -> Duration.ZERO);
 
-        // BFEEL-specific: ChronoPeriod * null → zero period
+        // ChronoPeriod * null → zero period
         map.put(
                 new CheckedPredicate((left, right) -> left instanceof 
ChronoPeriod && right == null, false),
                 (left, right) -> ComparablePeriod.ofMonths(0));
 
-        // BFEEL-specific: null * ChronoPeriod → zero period
+        // null * ChronoPeriod → zero period
         map.put(
                 new CheckedPredicate((left, right) -> left == null && right 
instanceof ChronoPeriod, false),
                 (left, right) -> ComparablePeriod.ofMonths(0));
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
index b9baf01bc2..11fe10fdd6 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
@@ -27,23 +27,37 @@ import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.chrono.ChronoPeriod;
 import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalQueries;
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
+import java.util.function.Supplier;
 
 import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.FEELDialect;
 import org.kie.dmn.feel.lang.ast.BaseNode;
 import org.kie.dmn.feel.lang.ast.InfixOpNode;
-import org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils;
+import org.kie.dmn.feel.lang.ast.infixexecutors.EqExecutor;
+import org.kie.dmn.feel.lang.types.BuiltInType;
 import org.kie.dmn.feel.lang.types.impl.ComparablePeriod;
+import org.kie.dmn.feel.runtime.Range;
 import org.kie.dmn.feel.util.BooleanEvalHelper;
-
-import static org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.*;
+import org.kie.dmn.feel.util.BuiltInTypeUtils;
+import org.kie.dmn.feel.util.DateTimeEvalHelper;
+
+import static 
org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.addLocalDateAndDuration;
+import static 
org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.commonManageInvalidParameters;
+import static 
org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.getBigDecimal;
+import static org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.math;
+import static 
org.kie.dmn.feel.lang.ast.infixexecutors.InfixExecutorUtils.subtractTemporals;
+import static org.kie.dmn.feel.util.DateTimeEvalHelper.valuedt;
+import static org.kie.dmn.feel.util.DateTimeEvalHelper.valuet;
 import static org.kie.dmn.feel.util.NumberEvalHelper.getBigDecimalOrNull;
 
 import ch.obermuhlner.math.big.BigDecimalMath;
@@ -121,64 +135,53 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
 
         // false AND anything → false (short‑circuit)
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.FALSE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, 
dialect)), false),
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.FALSE.equals(left), false),
+                (left, right) -> Boolean.FALSE);
+
+        // left not Boolean → treat as false
+        map.put(
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && dialect.equals(FEELDialect.BFEEL), false),
                 (left, right) -> Boolean.FALSE);
 
         // true AND true → true
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.TRUE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.TRUE.equals(left)
                         && Boolean.TRUE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.TRUE);
 
         // true AND false → false
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.TRUE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.TRUE.equals(left)
                         && Boolean.FALSE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.FALSE);
 
         // true AND otherwise → null
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.TRUE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.TRUE.equals(left)
                         && evalRight(right, ctx) == null, false),
                 (left, right) -> null);
 
         // otherwise AND true → null
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && Boolean.TRUE.equals(evalRight(right, ctx)), false),
                 (left, right) -> null);
 
         // otherwise AND false → false
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && Boolean.FALSE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.FALSE);
 
         // otherwise AND otherwise → null
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && evalRight(right, ctx) == null, false),
                 (left, right) -> null);
 
         return map;
     }
 
-    /**
-     * Builds the common 'Equal' operation map used by the dialect handlers.
-     * 
-     * @param ctx : Current Evaluation context
-     * @return : a Map of CheckedPredicate to BiFunction representing the 
common 'Equal' operations
-     */
-    Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonEqualOperations(EvaluationContext ctx) {
-        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
-
-        map.put(
-                new CheckedPredicate((left, right) -> true, false),
-                (left, right) -> BooleanEvalHelper.isEqual(left, right, 
dialect));
-        return map;
-    }
-
     /**
      * Builds the common 'Greater than Or EqualTo' operation map used by the 
dialect handlers.
      * 
@@ -187,15 +190,41 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
      */
     Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonGteOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
+        //        FEELDialect dialect = ctx.getFEELDialect();
+
+        // left or right is null → null
+        map.put(
+                new CheckedPredicate((left, right) -> left == null || right == 
null, false),
+                (left, right) -> null);
 
-        // left > right OR left == right
+        // both results are Boolean
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right instanceof Boolean, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    Boolean rightBool = (Boolean) right;
+                    return leftBool || rightBool;
+                });
+
+        // numeric/comparable >= logic
         map.put(
                 new CheckedPredicate((left, right) -> true, false),
-                (left, right) -> InfixExecutorUtils.or(
-                        BooleanEvalHelper.compare(left, right, dialect, 
(leftNum, rightNum) -> leftNum.compareTo(rightNum) > 0),
-                        BooleanEvalHelper.isEqual(left, right, dialect),
-                        ctx));
+                (left, right) -> {
+                    Boolean greater = compare(left, right,
+                            (leftNum, rightNum) -> leftNum.compareTo(rightNum) 
> 0,
+                            () -> null, // nullFallback for Default dialect
+                            () -> null // defaultFallback for unknown types
+                    );
+                    //Boolean equal = BooleanEvalHelper.isEqual(left, right, 
dialect);
+                    Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
+                            ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
+                            : null;
+                    if (greater == null && equal == null)
+                        return null;
+                    if (Boolean.TRUE.equals(greater) || 
Boolean.TRUE.equals(equal))
+                        return Boolean.TRUE;
+                    return Boolean.FALSE;
+                });
         return map;
     }
 
@@ -207,12 +236,18 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
      */
     Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonGtOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
-
-        // left > right
+        //  FEELDialect dialect = ctx.getFEELDialect();
+        // numeric/comparable > logic
         map.put(
                 new CheckedPredicate((left, right) -> true, false),
-                (left, right) -> BooleanEvalHelper.compare(left, right, 
dialect, (leftNum, rightNum) -> leftNum.compareTo(rightNum) > 0));
+                (left, right) -> {
+
+                    // default dialect: keep null
+                    return compare(left, right,
+                            (l, r) -> l.compareTo(r) > 0,
+                            () -> null,
+                            () -> null);
+                });
         return map;
     }
 
@@ -224,50 +259,62 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
      */
     Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonLteOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
 
-        // left < right OR left == right
+        // left or right is null → null
         map.put(
-                new CheckedPredicate((left, right) -> true, false),
-                (left, right) -> InfixExecutorUtils.or(
-                        BooleanEvalHelper.compare(left, right, dialect, 
(leftNum, rightNum) -> leftNum.compareTo(rightNum) < 0),
-                        BooleanEvalHelper.isEqual(left, right, dialect),
-                        ctx));
-        return map;
-    }
+                new CheckedPredicate((left, right) -> left == null || right == 
null, false),
+                (left, right) -> null);
 
-    /**
-     * Builds the common 'Less than' operation map used by the dialect 
handlers.
-     * 
-     * @param ctx : Current Evaluation context
-     * @return : a Map of CheckedPredicate to BiFunction representing the 
common 'Less than Or EqualTo' operations
-     */
-    Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonLtOperations(EvaluationContext ctx) {
-        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
+        // both results are Boolean
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right instanceof Boolean, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    Boolean rightBool = (Boolean) right;
+                    return leftBool || rightBool;
+                });
 
-        // left < right
+        // numeric/comparable ≤ logic
         map.put(
                 new CheckedPredicate((left, right) -> true, false),
-                (left, right) -> BooleanEvalHelper.compare(left, right, 
dialect, (leftNum, rightNum) -> leftNum.compareTo(rightNum) < 0));
+                (left, right) -> {
+                    Boolean less = compare(left, right,
+                            (l, r) -> l.compareTo(r) < 0,
+                            () -> null,
+                            () -> null);
+                    // Boolean equal = BooleanEvalHelper.isEqual(left, right, 
dialect);
+                    Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
+                            ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
+                            : null;
+
+                    if (less == null && equal == null) {
+                        return null;
+                    }
+                    if (Boolean.TRUE.equals(less) || 
Boolean.TRUE.equals(equal)) {
+                        return Boolean.TRUE;
+                    }
+                    return Boolean.FALSE;
+                });
         return map;
     }
 
     /**
-     * Builds the common 'Not EqualTo' operation map used by the dialect 
handlers.
+     * Builds the common 'Less than' operation map used by the dialect 
handlers.
      * 
      * @param ctx : Current Evaluation context
-     * @return : a Map of CheckedPredicate to BiFunction representing the 
common 'Not EqualTo' operations
+     * @return : a Map of CheckedPredicate to BiFunction representing the 
common 'Less than Or EqualTo' operations
      */
-    Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonNotEqualOperations(EvaluationContext ctx) {
+    Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonLtOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
-        FEELDialect dialect = ctx.getFEELDialect();
 
+        // numeric/comparable < logic
         map.put(
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
-                    Boolean result = BooleanEvalHelper.isEqual(left, right, 
dialect);
-                    return result != null ? !result : null;
+                    return compare(left, right,
+                            (l, r) -> l.compareTo(r) < 0,
+                            () -> null,
+                            () -> null);
                 });
         return map;
     }
@@ -281,45 +328,49 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
     Map<DefaultDialectHandler.CheckedPredicate, BiFunction<Object, Object, 
Object>> getCommonOrOperations(EvaluationContext ctx) {
         Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
         FEELDialect dialect = ctx.getFEELDialect();
-
         // true OR anything → true (short‑circuit)
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.TRUE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, 
dialect)), false),
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.TRUE.equals(left), false),
                 (left, right) -> Boolean.TRUE);
 
+        // left not Boolean → false
+        map.put(
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && dialect.equals(FEELDialect.BFEEL), false),
+                (left, right) -> Boolean.FALSE);
+
         // false OR true → true
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.FALSE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, 
dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.FALSE.equals(left)
                         && Boolean.TRUE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.TRUE);
 
         // false OR false → false
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.FALSE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, 
dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.FALSE.equals(left)
                         && Boolean.FALSE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.FALSE);
 
         // false OR otherwise → null
         map.put(
-                new CheckedPredicate((left, right) -> 
Boolean.FALSE.equals(BooleanEvalHelper.getBooleanOrDialectDefault(left, 
dialect))
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& Boolean.FALSE.equals(left)
                         && evalRight(right, ctx) == null, false),
                 (left, right) -> null);
 
         // otherwise OR true → true
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && Boolean.TRUE.equals(evalRight(right, ctx)), false),
                 (left, right) -> Boolean.TRUE);
 
         // otherwise OR false → null
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && Boolean.FALSE.equals(evalRight(right, ctx)), false),
                 (left, right) -> null);
 
         // otherwise OR otherwise → null
         map.put(
-                new CheckedPredicate((left, right) -> 
BooleanEvalHelper.getBooleanOrDialectDefault(left, dialect) == null
+                new CheckedPredicate((left, right) -> !(left instanceof 
Boolean) && !dialect.equals(FEELDialect.BFEEL)
                         && evalRight(right, ctx) == null, false),
                 (left, right) -> null);
 
@@ -678,4 +729,108 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
             return right;
         }
     }
+
+    /**
+     * Compares left and right operands using the given predicate and returns 
TRUE/FALSE accordingly
+     *
+     * @param left
+     * @param right
+     * @param op
+     * @return
+     */
+    public static Boolean compare(Object left, Object right, 
BiPredicate<Comparable, Comparable> op, Supplier<Boolean> nullFallback,
+            Supplier<Boolean> defaultFallback) {
+        if (nullFallback == null || defaultFallback == null) {
+            throw new IllegalArgumentException("Fallback suppliers must not be 
null");
+        }
+        if (left == null || right == null) {
+            return nullFallback.get();
+        }
+        if (left instanceof ChronoPeriod && right instanceof ChronoPeriod) {
+            // periods have special compare semantics in FEEL as it ignores 
"days". Only months and years are compared
+            Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left);
+            Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right);
+            return op.test(l, r);
+        }
+        if (left instanceof TemporalAccessor && right instanceof 
TemporalAccessor) {
+            // Handle specific cases when both time / datetime
+            TemporalAccessor l = (TemporalAccessor) left;
+            TemporalAccessor r = (TemporalAccessor) right;
+            if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.TIME) {
+                return op.test(valuet(l), valuet(r));
+            } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.DATE_TIME) {
+                return op.test(valuedt(l, r.query(TemporalQueries.zone())), 
valuedt(r, l.query(TemporalQueries.zone())));
+            }
+        }
+        if (left instanceof Number && right instanceof Number) {
+            // Handle specific cases when both are Number, converting both to 
BigDecimal
+            BigDecimal l = getBigDecimalOrNull(left);
+            BigDecimal r = getBigDecimalOrNull(right);
+            return op.test(l, r);
+        }
+        // last fallback:
+        if ((left instanceof String && right instanceof String) ||
+                (left instanceof Boolean && right instanceof Boolean) ||
+                (left instanceof Comparable && 
left.getClass().isAssignableFrom(right.getClass()))) {
+            Comparable<?> l = (Comparable<?>) left;
+            Comparable<?> r = (Comparable<?>) right;
+            return op.test(l, r);
+        }
+        return defaultFallback.get();
+    }
+
+    /**
+     * Compares left and right for equality applying FEEL semantics to 
specific data types
+     *
+     * @param left : the first object to compare
+     * @param right : the second object to compare
+     * @param nullFallback : supplier invoked when either argument is null; 
must not be null
+     * @param defaultFallback supplier invoked when no comparison rule applies 
or comparison fails; must not be null
+     * @return : result of the provided fallback suppliers depending on the 
case
+     */
+    public static Boolean isEqual(Object left, Object right, Supplier<Boolean> 
nullFallback, Supplier<Boolean> defaultFallback) {
+        if (nullFallback == null || defaultFallback == null) {
+            throw new IllegalArgumentException("Fallback suppliers must not be 
null");
+        }
+        if (left == null || right == null) {
+            return nullFallback.get();
+        }
+
+        // spec defines that "a=[a]", i.e., singleton collections should be 
treated as the single element
+        // and vice-versa
+        if (left instanceof Collection && !(right instanceof Collection) && 
((Collection) left).size() == 1) {
+            left = ((Collection) left).toArray()[0];
+        } else if (right instanceof Collection && !(left instanceof 
Collection) && ((Collection) right).size() == 1) {
+            right = ((Collection) right).toArray()[0];
+        }
+
+        if (left instanceof Range && right instanceof Range) {
+            return BooleanEvalHelper.isEqual((Range) left, (Range) right);
+        } else if (left instanceof Iterable && right instanceof Iterable) {
+            return BooleanEvalHelper.isEqual((Iterable) left, (Iterable) 
right);
+        } else if (left instanceof Map && right instanceof Map) {
+            return BooleanEvalHelper.isEqual((Map) left, (Map) right);
+        } else if (left instanceof ChronoPeriod && right instanceof 
ChronoPeriod) {
+            // periods have special compare semantics in FEEL as it ignores 
"days". Only months and years are compared
+            Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left);
+            Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right);
+            return isEqual(l, r, nullFallback, defaultFallback);
+        } else if (left instanceof TemporalAccessor && right instanceof 
TemporalAccessor) {
+            // Handle specific cases when both time / datetime
+            TemporalAccessor l = (TemporalAccessor) left;
+            TemporalAccessor r = (TemporalAccessor) right;
+            if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.TIME) {
+                return isEqual(DateTimeEvalHelper.valuet(l), 
DateTimeEvalHelper.valuet(r), nullFallback, defaultFallback);
+            } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.DATE_TIME) {
+                return isEqual(DateTimeEvalHelper.valuedt(l, 
r.query(TemporalQueries.zone())), DateTimeEvalHelper.valuedt(r, 
l.query(TemporalQueries.zone())), nullFallback, defaultFallback);
+            } // fallback; continue:
+        }
+        //return compare(left, right, feelDialect, (l, r) -> l.compareTo(r) == 
0);
+        // Fallback: Comparable equality
+        return compare(left, right,
+                (l, r) -> l.compareTo(r) == 0,
+                nullFallback,
+                defaultFallback);
+    }
+
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
index ac0e21da70..c43795df14 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
@@ -18,8 +18,6 @@
  */
 package org.kie.dmn.feel.lang.ast.dialectHandlers;
 
-import org.kie.dmn.feel.lang.EvaluationContext;
-
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.chrono.ChronoPeriod;
@@ -28,6 +26,8 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.BiFunction;
 
+import org.kie.dmn.feel.lang.EvaluationContext;
+
 /**
  * Handler implementation of the DialectHandler interface providing FEEL 
specific
  * functionalities
@@ -93,32 +93,155 @@ public class FEELDialectHandler extends 
DefaultDialectHandler implements Dialect
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getEqualOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonEqualOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+        map.put(
+                new CheckedPredicate((left, right) -> left == null && right == 
null, false),
+                (left, right) -> Boolean.TRUE);
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> isEqual(left, right,
+                        () -> Boolean.FALSE, () -> null));
+
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getGteOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonGteOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // left is Boolean, right is null
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right == null, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    if (Boolean.FALSE.equals(leftBool)) {
+                        return null; // false + null → null
+                    }
+                    return Boolean.TRUE; // true + null → true
+                });
+
+        // right is Boolean, left is null
+        map.put(
+                new CheckedPredicate((left, right) -> right instanceof Boolean 
&& left == null, false),
+                (left, right) -> {
+                    Boolean rightBool = (Boolean) right;
+                    if (Boolean.FALSE.equals(rightBool)) {
+                        return null; // null + false → null
+                    }
+                    return Boolean.TRUE; // null + true → true
+                });
+        // Fall back to common >= operations for all other cases
+        map.putAll(getCommonGteOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getGtOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonGtOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // left is Boolean, right is null
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right == null, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    if (Boolean.FALSE.equals(leftBool)) {
+                        return null; // false + null → null
+                    }
+                    return Boolean.TRUE; // true + null → true
+                });
+
+        // right is Boolean, left is null
+        map.put(
+                new CheckedPredicate((left, right) -> right instanceof Boolean 
&& left == null, false),
+                (left, right) -> {
+                    Boolean rightBool = (Boolean) right;
+                    if (Boolean.FALSE.equals(rightBool)) {
+                        return null; // null + false → null
+                    }
+                    return Boolean.TRUE; // null + true → true
+                });
+
+        // Fall back to common > operations
+        map.putAll(getCommonGtOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getLteOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonLteOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // left is Boolean, right is null
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right == null, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    if (Boolean.FALSE.equals(leftBool)) {
+                        return null; // false + null → null
+                    }
+                    return Boolean.TRUE; // true + null → true
+                });
+
+        // right is Boolean, left is null
+        map.put(
+                new CheckedPredicate((left, right) -> right instanceof Boolean 
&& left == null, false),
+                (left, right) -> {
+                    Boolean rightBool = (Boolean) right;
+                    if (Boolean.FALSE.equals(rightBool)) {
+                        return null; // null + false → null
+                    }
+                    return Boolean.TRUE; // null + true → true
+                });
+
+        // Fall back to common ≤ operations
+        map.putAll(getCommonLteOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getLtOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonLtOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // left is Boolean, right is null
+        map.put(
+                new CheckedPredicate((left, right) -> left instanceof Boolean 
&& right == null, false),
+                (left, right) -> {
+                    Boolean leftBool = (Boolean) left;
+                    if (Boolean.FALSE.equals(leftBool)) {
+                        return null; // false + null → null
+                    }
+                    return Boolean.TRUE; // true + null → true
+                });
+
+        // right is Boolean, left is null
+        map.put(
+                new CheckedPredicate((left, right) -> right instanceof Boolean 
&& left == null, false),
+                (left, right) -> {
+                    Boolean rightBool = (Boolean) right;
+                    if (Boolean.FALSE.equals(rightBool)) {
+                        return null; // null + false → null
+                    }
+                    return Boolean.TRUE; // null + true → true
+                });
+
+        map.putAll(getCommonLtOperations(ctx));
+        return map;
     }
 
     @Override
     public Map<CheckedPredicate, BiFunction<Object, Object, Object>> 
getNotEqualOperations(EvaluationContext ctx) {
-        return new LinkedHashMap<>(getCommonNotEqualOperations(ctx));
+        Map<CheckedPredicate, BiFunction<Object, Object, Object>> map = new 
LinkedHashMap<>();
+
+        // Shortcut: null != null → false
+        map.put(
+                new CheckedPredicate((left, right) -> left == null && right == 
null, false),
+                (left, right) -> Boolean.FALSE);
+        map.put(
+                new CheckedPredicate((left, right) -> true, false),
+                (left, right) -> {
+                    Boolean result = isEqual(left, right, () -> Boolean.FALSE, 
() -> null);
+                    return result != null ? !result : null;
+                });
+        return map;
     }
 
     /**
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java
index b5664986b4..1377426090 100644
--- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java
+++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java
@@ -18,15 +18,13 @@
  */
 package org.kie.dmn.feel.runtime;
 
-import org.kie.dmn.feel.lang.FEELDialect;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
+import org.kie.dmn.feel.lang.EvaluationContext;
 
 public interface Range {
 
     enum RangeBoundary {
-        OPEN, CLOSED;
+        OPEN,
+        CLOSED;
     }
 
     RangeBoundary getLowBoundary();
@@ -37,7 +35,9 @@ public interface Range {
 
     RangeBoundary getHighBoundary();
 
-    Boolean includes(FEELDialect feelDialect, Object param);
+    //Boolean includes(FEELDialect feelDialect, Object param);
+
+    Boolean includes(EvaluationContext ctx, Object param);
 
     boolean isWithUndefined();
 
@@ -45,5 +45,4 @@ public interface Range {
 
     Comparable getEnd();
 
-
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/DecisionTableFunction.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/DecisionTableFunction.java
index 8232247936..00c0493a7a 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/DecisionTableFunction.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/DecisionTableFunction.java
@@ -33,11 +33,7 @@ import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.impl.FEELBuilder;
 import org.kie.dmn.feel.runtime.Range;
 import org.kie.dmn.feel.runtime.UnaryTest;
-import org.kie.dmn.feel.runtime.decisiontables.DTDecisionRule;
-import org.kie.dmn.feel.runtime.decisiontables.DTInputClause;
-import org.kie.dmn.feel.runtime.decisiontables.DTOutputClause;
-import org.kie.dmn.feel.runtime.decisiontables.DecisionTableImpl;
-import org.kie.dmn.feel.runtime.decisiontables.HitPolicy;
+import org.kie.dmn.feel.runtime.decisiontables.*;
 import org.kie.dmn.feel.runtime.events.FEELEventBase;
 import org.kie.dmn.feel.util.Msg;
 import org.slf4j.Logger;
@@ -48,30 +44,30 @@ public class DecisionTableFunction
 
     public static final DecisionTableFunction INSTANCE = new 
DecisionTableFunction();
 
-    private static final Logger LOG = LoggerFactory.getLogger( 
DecisionTableFunction.class );
+    private static final Logger LOG = 
LoggerFactory.getLogger(DecisionTableFunction.class);
 
     private DecisionTableFunction() {
-        super( "decision table" );
+        super("decision table");
     }
 
     /**
-     @param inputExpressionList a list of the N>=0 input expressions in 
display order
-     @param inputValuesList * a list of N input values, corresponding to the 
input expressions. Each
-     list element is a unary tests literal (see below).
-     @param outputs * a name (a string matching grammar rule 27) or a list of 
M>0 names
-     @param outputValues * if outputs is a list, then output values is a list 
of lists of values, one list
-     per output; else output values is a list of values for the one output.
-     Each value is a string.
-     @param ruleList a list of R>0 rules. A rule is a list of N input entries 
followed by M
-     output entries. An input entry is a unary tests literal. An output entry 
is
-     an expression represented as a string.
-     @param hitPolicy * one of: "U", "A", “P”, “F”, "R", "O", "C", "C+", "C#", 
"C<", “C>”
-     (default is "U")
-     @param defaultOutputValue * if outputs is a list, then default output 
value is a context with entries
-     composed of outputs and output values; else default output value is one
-     of the output values.
+     * @param inputExpressionList a list of the N>=0 input expressions in 
display order
+     * @param inputValuesList * a list of N input values, corresponding to the 
input expressions. Each
+     *        list element is a unary tests literal (see below).
+     * @param outputs * a name (a string matching grammar rule 27) or a list 
of M>0 names
+     * @param outputValues * if outputs is a list, then output values is a 
list of lists of values, one list
+     *        per output; else output values is a list of values for the one 
output.
+     *        Each value is a string.
+     * @param ruleList a list of R>0 rules. A rule is a list of N input 
entries followed by M
+     *        output entries. An input entry is a unary tests literal. An 
output entry is
+     *        an expression represented as a string.
+     * @param hitPolicy * one of: "U", "A", “P”, “F”, "R", "O", "C", "C+", 
"C#", "C<", “C>”
+     *        (default is "U")
+     * @param defaultOutputValue * if outputs is a list, then default output 
value is a context with entries
+     *        composed of outputs and output values; else default output value 
is one
+     *        of the output values.
      */
-    public Object invoke(@ParameterName("ctx") EvaluationContext ctx, 
+    public Object invoke(@ParameterName("ctx") EvaluationContext ctx,
             @ParameterName("outputs") Object outputs,
             @ParameterName("input expression list") Object inputExpressionList,
             @ParameterName("input values list") List<?> inputValuesList,
@@ -81,62 +77,63 @@ public class DecisionTableFunction
             @ParameterName("default output value") Object defaultOutputValue) {
         // input expression list can have a single element or be a list
         // TODO isn't ^ conflicting with the specs page 136 "input expression 
list: a LIST of the"
-        List<String> inputExpressions = inputExpressionList instanceof List ? 
(List) inputExpressionList : Collections.singletonList( (String) 
inputExpressionList );
+        List<String> inputExpressions = inputExpressionList instanceof List ? 
(List) inputExpressionList : Collections.singletonList((String) 
inputExpressionList);
 
         List<DTInputClause> inputs;
-        if ( inputValuesList != null ) {
-            List<UnaryTest> inputValues = inputValuesList.stream().map( o -> 
toUnaryTest(ctx, o) ).collect( Collectors.toList() );
-            if ( inputValues.size() != inputExpressions.size() ) {
+        if (inputValuesList != null) {
+            List<UnaryTest> inputValues = inputValuesList.stream().map(o -> 
toUnaryTest(ctx, o)).collect(Collectors.toList());
+            if (inputValues.size() != inputExpressions.size()) {
                 // TODO handle compilation error
             }
             // zip inputExpression with its inputValue
-            inputs = IntStream.range( 0, inputExpressions.size() )
-                    .mapToObj( i -> new DTInputClause( inputExpressions.get( i 
), inputValuesList.toString(), Collections.singletonList( inputValues.get( i ) 
), null, false) )
-                    .collect( Collectors.toList() );
+            inputs = IntStream.range(0, inputExpressions.size())
+                    .mapToObj(i -> new DTInputClause(inputExpressions.get(i), 
inputValuesList.toString(), Collections.singletonList(inputValues.get(i)), 
null, false))
+                    .collect(Collectors.toList());
         } else {
-            inputs = inputExpressions.stream().map( ie -> new DTInputClause( 
ie, null, null, null, false ) ).collect( Collectors.toList() );
+            inputs = inputExpressions.stream().map(ie -> new DTInputClause(ie, 
null, null, null, false)).collect(Collectors.toList());
         }
 
-        List<String> parseOutputs = outputs instanceof List ? (List) outputs : 
Collections.singletonList( (String) outputs );
+        List<String> parseOutputs = outputs instanceof List ? (List) outputs : 
Collections.singletonList((String) outputs);
         List<DTOutputClause> outputClauses;
-        if ( outputValues != null ) {
-            if ( parseOutputs.size() == 1 ) {
+        if (outputValues != null) {
+            if (parseOutputs.size() == 1) {
                 outputClauses = new ArrayList<>();
-                List<UnaryTest> outputValuesCompiled = objectToUnaryTestList( 
ctx, Collections.singletonList( (List<Object>) outputValues ) ).get(0);
-                outputClauses.add( new DTOutputClause( parseOutputs.get( 0 ), 
outputValuesCompiled ) );
+                List<UnaryTest> outputValuesCompiled = 
objectToUnaryTestList(ctx, Collections.singletonList((List<Object>) 
outputValues)).get(0);
+                outputClauses.add(new DTOutputClause(parseOutputs.get(0), 
outputValuesCompiled));
             } else {
-                List<List<UnaryTest>> listOfList = objectToUnaryTestList( ctx, 
(List<List<Object>>) outputValues );
+                List<List<UnaryTest>> listOfList = objectToUnaryTestList(ctx, 
(List<List<Object>>) outputValues);
                 // zip inputExpression with its inputValue
-                outputClauses = IntStream.range( 0, parseOutputs.size() )
-                        .mapToObj( i -> new DTOutputClause( parseOutputs.get( 
i ), listOfList.get( i ) ) )
-                        .collect( Collectors.toList() );
+                outputClauses = IntStream.range(0, parseOutputs.size())
+                        .mapToObj(i -> new DTOutputClause(parseOutputs.get(i), 
listOfList.get(i)))
+                        .collect(Collectors.toList());
             }
         } else {
-            outputClauses = parseOutputs.stream().map( out -> new 
DTOutputClause( out, null ) ).collect( Collectors.toList() );
+            outputClauses = parseOutputs.stream().map(out -> new 
DTOutputClause(out, null)).collect(Collectors.toList());
         }
 
         // TODO parse default output value.
         FEEL feel = FEELBuilder.builder().build();
-        List<DTDecisionRule> decisionRules = IntStream.range( 0, 
ruleList.size() )
-                .mapToObj( index -> toDecisionRule( ctx, feel, index, 
ruleList.get( index ), inputExpressions.size() ) )
-                .collect( Collectors.toList() );
+        List<DTDecisionRule> decisionRules = IntStream.range(0, 
ruleList.size())
+                .mapToObj(index -> toDecisionRule(ctx, feel, index, 
ruleList.get(index), inputExpressions.size()))
+                .collect(Collectors.toList());
 
         // TODO is there a way to avoid UUID and get from _evaluation_ ctx the 
name of the wrapping context? 
         // TODO also in this case it is using an ad-hoc created FEEL instance 
instead of the "hosted" one.
-        DecisionTableImpl dti = new 
DecisionTableImpl(UUID.randomUUID().toString(), inputExpressions, inputs, 
outputClauses, decisionRules, HitPolicy.fromString(hitPolicy), 
FEELBuilder.builder().build());
-        return new DTInvokerFunction( dti );
+        DecisionTableImpl dti =
+                new DecisionTableImpl(UUID.randomUUID().toString(), 
inputExpressions, inputs, outputClauses, decisionRules, 
HitPolicy.fromString(hitPolicy), FEELBuilder.builder().build());
+        return new DTInvokerFunction(dti);
     }
 
     protected List<List<UnaryTest>> objectToUnaryTestList(EvaluationContext 
ctx, List<List<Object>> values) {
-        if ( values == null || values.isEmpty() ) {
+        if (values == null || values.isEmpty()) {
             return Collections.emptyList();
         }
         List<List<UnaryTest>> tests = new ArrayList<>();
-        for ( List<Object> lo : values ) {
-            List<UnaryTest> uts = new ArrayList<>(  );
+        for (List<Object> lo : values) {
+            List<UnaryTest> uts = new ArrayList<>();
             tests.add(uts);
-            for( Object t : lo ) {
-                uts.add( toUnaryTest( ctx, t ) );
+            for (Object t : lo) {
+                uts.add(toUnaryTest(ctx, t));
             }
         }
         return tests;
@@ -144,6 +141,7 @@ public class DecisionTableFunction
 
     /**
      * Convert row to DTDecisionRule
+     * 
      * @param mainCtx the main context is used to identify the hosted 
FEELEventManager
      * @param embeddedFEEL a possibly cached embedded FEEL to compile the 
output expression, error will be reported up to the mainCtx
      * @param index
@@ -153,18 +151,18 @@ public class DecisionTableFunction
      */
     private static DTDecisionRule toDecisionRule(EvaluationContext mainCtx, 
FEEL embeddedFEEL, int index, List<?> rule, int inputSize) {
         // TODO should be check indeed block of inputSize n inputs, followed 
by block of outputs.
-        DTDecisionRule dr = new DTDecisionRule( index, null );
-        for ( int i = 0; i < rule.size(); i++ ) {
-            Object o = rule.get( i );
-            if ( i < inputSize ) {
-                dr.getInputEntry().add( toUnaryTest( mainCtx, o ) );
+        DTDecisionRule dr = new DTDecisionRule(index, null);
+        for (int i = 0; i < rule.size(); i++) {
+            Object o = rule.get(i);
+            if (i < inputSize) {
+                dr.getInputEntry().add(toUnaryTest(mainCtx, o));
             } else {
-                FEELEventListener ruleListener = event -> mainCtx.notifyEvt( 
() -> new FEELEventBase(event.getSeverity(),
-                                                                               
                      
Msg.createMessage(Msg.ERROR_COMPILE_EXPR_DT_FUNCTION_RULE_IDX, index+1, 
event.getMessage()),
-                                                                               
                      event.getSourceException()));
+                FEELEventListener ruleListener = event -> mainCtx.notifyEvt(() 
-> new FEELEventBase(event.getSeverity(),
+                        
Msg.createMessage(Msg.ERROR_COMPILE_EXPR_DT_FUNCTION_RULE_IDX, index + 1, 
event.getMessage()),
+                        event.getSourceException()));
                 embeddedFEEL.addListener(ruleListener);
                 CompiledExpression compiledExpression = 
embeddedFEEL.compile((String) o, embeddedFEEL.newCompilerContext());
-                dr.getOutputEntry().add( compiledExpression );
+                dr.getOutputEntry().add(compiledExpression);
                 embeddedFEEL.removeListener(ruleListener);
             }
         }
@@ -172,23 +170,23 @@ public class DecisionTableFunction
     }
 
     private static UnaryTest toUnaryTest(EvaluationContext ctx, Object o) {
-        if ( o instanceof UnaryTest ) {
+        if (o instanceof UnaryTest) {
             return (UnaryTest) o;
-        } else if ( o instanceof Range ) {
+        } else if (o instanceof Range) {
             return (c, x) -> {
                 try {
-                    return ((Range) o).includes(ctx.getFEELDialect(), x );
-                } catch ( Exception e ) {
-                    ctx.notifyEvt( () -> new FEELEventBase( 
FEELEvent.Severity.ERROR,
-                                                            Msg.createMessage( 
Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, o.toString(), x.toString() 
),
-                                                            e ) );
+                    return ((Range) o).includes(ctx, x);
+                } catch (Exception e) {
+                    ctx.notifyEvt(() -> new 
FEELEventBase(FEELEvent.Severity.ERROR,
+                            
Msg.createMessage(Msg.EXPRESSION_IS_RANGE_BUT_VALUE_IS_NOT_COMPARABLE, 
o.toString(), x.toString()),
+                            e));
                     throw e;
                 }
             };
-        } else if ( o instanceof List ) {
-            return (c, x) -> ((List<?>) o).contains( x );
+        } else if (o instanceof List) {
+            return (c, x) -> ((List<?>) o).contains(x);
         } else {
-            return (c, x) -> x.equals( o );
+            return (c, x) -> x.equals(o);
         }
     }
 
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java
index bf2acf7f1f..7f6a011972 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java
@@ -21,7 +21,7 @@ package org.kie.dmn.feel.runtime.functions;
 import java.time.chrono.ChronoPeriod;
 import java.time.temporal.TemporalAccessor;
 
-import org.kie.dmn.feel.lang.FEELDialect;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DefaultDialectHandler;
 import org.kie.dmn.feel.lang.types.BuiltInType;
 import org.kie.dmn.feel.runtime.FEELBooleanFunction;
 import org.kie.dmn.feel.util.BooleanEvalHelper;
@@ -48,8 +48,11 @@ public class IsFunction extends BaseFEELFunction implements 
FEELBooleanFunction
                 return 
FEELFnResult.ofResult(BooleanEvalHelper.isEqualDateTimeInSemanticD(left, 
right));
             } // fallback; continue:
         }
-        Boolean fallback = BooleanEvalHelper.isEqual(value1, value2, 
FEELDialect.FEEL); // if null implying they are not the same semantic domain 
value.
-        return FEELFnResult.ofResult(fallback != null ? fallback : 
Boolean.FALSE);
+        //Boolean fallback = BooleanEvalHelper.isEqual(value1, value2, 
FEELDialect.FEEL); // if null implying they are not the same semantic domain 
value
+        // If the values are not in the same domain, result should be false.
+        Boolean fallback = DefaultDialectHandler.isEqual(value1, value2, () -> 
Boolean.FALSE, () -> Boolean.FALSE);
+        return FEELFnResult.ofResult(fallback);
+
     }
 
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java
index d70467f79d..c466153ff1 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java
@@ -20,11 +20,11 @@ package org.kie.dmn.feel.runtime.impl;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
-import java.util.function.BiPredicate;
 
-import org.kie.dmn.feel.lang.FEELDialect;
+import org.kie.dmn.feel.lang.EvaluationContext;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandler;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DialectHandlerFactory;
 import org.kie.dmn.feel.runtime.Range;
-import org.kie.dmn.feel.util.BooleanEvalHelper;
 
 import static org.kie.dmn.feel.lang.ast.UnaryTestNode.UnaryOperator.GT;
 import static org.kie.dmn.feel.lang.ast.UnaryTestNode.UnaryOperator.GTE;
@@ -36,8 +36,8 @@ public class RangeImpl
 
     private RangeBoundary lowBoundary;
     private RangeBoundary highBoundary;
-    private Comparable    lowEndPoint;
-    private Comparable    highEndPoint;
+    private Comparable lowEndPoint;
+    private Comparable highEndPoint;
     private boolean withUndefined = false;
 
     public RangeImpl() {
@@ -72,7 +72,7 @@ public class RangeImpl
     }
 
     @Override
-    public Boolean includes(FEELDialect feelDialect, Object param) {
+    public Boolean includes(EvaluationContext ctx, Object param) {
         if (param == null) {
             return null;
         }
@@ -80,15 +80,15 @@ public class RangeImpl
             if (highEndPoint == null || highEndPoint instanceof 
UndefinedValueComparable) {
                 return null;
             } else if (lowEndPoint != null) { // it means it is 
UndefinedValueComparable
-                return negInfRangeIncludes(feelDialect, param);
+                return negInfRangeIncludes(ctx, param);
             } else {
                 return false;
             }
         } else {
             if (highEndPoint instanceof UndefinedValueComparable) {
-                return posInfRangeIncludes(feelDialect, param);
+                return posInfRangeIncludes(ctx, param);
             } else if (highEndPoint != null) {
-                return finiteRangeIncludes(feelDialect, param);
+                return finiteRangeIncludes(ctx, param);
             } else {
                 return false;
             }
@@ -102,7 +102,7 @@ public class RangeImpl
 
     @Override
     public Comparable getStart() {
-        if(lowEndPoint instanceof BigDecimal) {
+        if (lowEndPoint instanceof BigDecimal) {
             BigDecimal start = (BigDecimal) lowEndPoint;
             start = lowBoundary == Range.RangeBoundary.OPEN ? 
start.add(BigDecimal.ONE) : start;
             return start;
@@ -128,64 +128,73 @@ public class RangeImpl
         return highEndPoint;
     }
 
-    private Boolean finiteRangeIncludes(FEELDialect feelDialect, Object param) 
{
+    private Boolean finiteRangeIncludes(EvaluationContext ctx, Object param) {
+        DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         if (lowBoundary == RangeBoundary.OPEN && highBoundary == 
RangeBoundary.OPEN) {
-            return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, r) 
-> l.compareTo(r) < 0) , compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) > 0), param);
+            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) < 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0), param);
+            return bothOrThrow((Boolean) handler.executeLt(lowEndPoint, param, 
ctx), (Boolean) handler.executeGt(highEndPoint, param, ctx), param);
         } else if (lowBoundary == RangeBoundary.OPEN && highBoundary == 
RangeBoundary.CLOSED) {
-            return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, r) 
-> l.compareTo(r) < 0) , compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) >= 0), param);
+            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) < 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
+            return bothOrThrow((Boolean) handler.executeLt(lowEndPoint, param, 
ctx), (Boolean) handler.executeGte(highEndPoint, param, ctx), param);
         } else if (lowBoundary == RangeBoundary.CLOSED && highBoundary == 
RangeBoundary.OPEN) {
-            return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, r) 
-> l.compareTo(r) <= 0) , compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) > 0), param);
+            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) <= 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0), param);
+            return bothOrThrow((Boolean) handler.executeLte(lowEndPoint, 
param, ctx), (Boolean) handler.executeGt(highEndPoint, param, ctx), param);
         } else if (lowBoundary == RangeBoundary.CLOSED && highBoundary == 
RangeBoundary.CLOSED) {
-            return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, r) 
-> l.compareTo(r) <= 0) , compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) >= 0), param);
+            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) <= 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
+            return bothOrThrow((Boolean) handler.executeLte(lowEndPoint, 
param, ctx), (Boolean) handler.executeGte(highEndPoint, param, ctx), param);
         }
         throw new RuntimeException("unknown boundary combination");
     }
 
-    private Boolean posInfRangeIncludes(FEELDialect feelDialect, Object param) 
{
+    private Boolean posInfRangeIncludes(EvaluationContext ctx, Object param) {
+        DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         if (lowBoundary == RangeBoundary.OPEN) {
-            return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0);
+            //return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0);
+            return (Boolean) handler.executeLt(lowEndPoint, param, ctx);
         } else {
-            return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0);
+            //return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0);
+            return (Boolean) handler.executeLte(lowEndPoint, param, ctx);
         }
     }
 
-    private Boolean negInfRangeIncludes(FEELDialect feelDialect, Object param) 
{
+    private Boolean negInfRangeIncludes(EvaluationContext ctx, Object param) {
+        DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         if (highBoundary == RangeBoundary.OPEN) {
-            return compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) > 0);
+            //return compare(ctx, highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0);
+            return (Boolean) handler.executeGt(highEndPoint, param, ctx);
         } else {
-            return compare(feelDialect, highEndPoint, param,  (l, r) -> 
l.compareTo(r) >= 0);
+            //return compare(ctx, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0);
+            return (Boolean) handler.executeGte(highEndPoint, param, ctx);
         }
     }
-    
+
     private Boolean bothOrThrow(Boolean left, Boolean right, Object param) {
         if (left == null || right == null) {
-            throw new 
IllegalArgumentException("Range.include("+classOf(param)+") not comparable with 
"+classOf(lowEndPoint)+", "+classOf(highEndPoint));
+            throw new IllegalArgumentException("Range.include(" + 
classOf(param) + ") not comparable with " + classOf(lowEndPoint) + ", " + 
classOf(highEndPoint));
         }
         return left && right;
     }
-    
+
     private static String classOf(Object p) {
         return p != null ? p.getClass().toString() : "null";
     }
-    
-    private static Boolean compare(FEELDialect feelDialect, Comparable left, 
Object right, BiPredicate<Comparable, Comparable> op) {
-        if (left.getClass().isAssignableFrom(right.getClass())) { // short path
-                return op.test(left, (Comparable) right);
-        }
-        return BooleanEvalHelper.compare(left, right, feelDialect, op); // 
defer to full DMN/FEEL semantic
-    }
 
     @Override
     public boolean equals(Object o) {
-        if ( this == o ) return true;
-        if ( !(o instanceof RangeImpl) ) return false;
+        if (this == o)
+            return true;
+        if (!(o instanceof RangeImpl))
+            return false;
 
         RangeImpl range = (RangeImpl) o;
 
-        if ( lowBoundary != range.lowBoundary ) return false;
-        if ( highBoundary != range.highBoundary ) return false;
-        if ( lowEndPoint != null ? !lowEndPoint.equals( range.lowEndPoint ) : 
range.lowEndPoint != null ) return false;
-        return highEndPoint != null ? highEndPoint.equals( range.highEndPoint 
) : range.highEndPoint == null;
+        if (lowBoundary != range.lowBoundary)
+            return false;
+        if (highBoundary != range.highBoundary)
+            return false;
+        if (lowEndPoint != null ? !lowEndPoint.equals(range.lowEndPoint) : 
range.lowEndPoint != null)
+            return false;
+        return highEndPoint != null ? highEndPoint.equals(range.highEndPoint) 
: range.highEndPoint == null;
 
     }
 
@@ -207,7 +216,7 @@ public class RangeImpl
         return (lowBoundary == RangeBoundary.OPEN ? "(" : "[") +
                 " " + lowEndPoint +
                 " .. " + highEndPoint +
-                " " + ( highBoundary == RangeBoundary.OPEN ? ")" : "]" );
+                " " + (highBoundary == RangeBoundary.OPEN ? ")" : "]");
     }
 
     private String withUndefinedtoString() {
@@ -232,4 +241,5 @@ public class RangeImpl
         sb.append(" )");
         return sb.toString();
     }
+
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java
index 559b080f30..6ff976aa41 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java
@@ -18,131 +18,23 @@
  */
 package org.kie.dmn.feel.util;
 
-import java.math.BigDecimal;
 import java.time.ZoneId;
-import java.time.chrono.ChronoPeriod;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQueries;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Optional;
-import java.util.function.BiPredicate;
 
-import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.FEELDialect;
-import org.kie.dmn.feel.lang.ast.BaseNode;
-import org.kie.dmn.feel.lang.ast.InfixOpNode;
-import org.kie.dmn.feel.lang.types.BuiltInType;
-import org.kie.dmn.feel.lang.types.impl.ComparablePeriod;
+import org.kie.dmn.feel.lang.ast.dialectHandlers.DefaultDialectHandler;
 import org.kie.dmn.feel.runtime.Range;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.kie.dmn.feel.util.DateTimeEvalHelper.valuedt;
-import static org.kie.dmn.feel.util.DateTimeEvalHelper.valuet;
-import static org.kie.dmn.feel.util.NumberEvalHelper.getBigDecimalOrNull;
-
 public class BooleanEvalHelper {
     public static final Logger LOG = 
LoggerFactory.getLogger(BooleanEvalHelper.class);
 
-    public static Boolean getBooleanOrNull(Object value) {
-        if (!(value instanceof Boolean)) {
-            return null;
-        }
-        return (Boolean) value;
-    }
-
-    /**
-     * Compares left and right operands using the given predicate and returns 
TRUE/FALSE accordingly
-     *
-     * @param left
-     * @param right
-     * @param op
-     * @return
-     */
-    public static Boolean compare(Object left, Object right, FEELDialect 
feelDialect, BiPredicate<Comparable, Comparable> op) {
-        if (left == null || right == null) {
-            return getBooleanOrDialectDefault(null, feelDialect);
-        }
-        if (left instanceof ChronoPeriod && right instanceof ChronoPeriod) {
-            // periods have special compare semantics in FEEL as it ignores 
"days". Only months and years are compared
-            Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left);
-            Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right);
-            return op.test(l, r);
-        }
-        if (left instanceof TemporalAccessor && right instanceof 
TemporalAccessor) {
-            // Handle specific cases when both time / datetime
-            TemporalAccessor l = (TemporalAccessor) left;
-            TemporalAccessor r = (TemporalAccessor) right;
-            if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.TIME) {
-                return op.test(valuet(l), valuet(r));
-            } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.DATE_TIME) {
-                return op.test(valuedt(l, r.query(TemporalQueries.zone())), 
valuedt(r, l.query(TemporalQueries.zone())));
-            }
-        }
-        if (left instanceof Number && right instanceof Number) {
-            // Handle specific cases when both are Number, converting both to 
BigDecimal
-            BigDecimal l = getBigDecimalOrNull(left);
-            BigDecimal r = getBigDecimalOrNull(right);
-            return op.test(l, r);
-        }
-        // last fallback:
-        if ((left instanceof String && right instanceof String) ||
-                (left instanceof Boolean && right instanceof Boolean) ||
-                (left instanceof Comparable && 
left.getClass().isAssignableFrom(right.getClass()))) {
-            Comparable<?> l = (Comparable<?>) left;
-            Comparable<?> r = (Comparable<?>) right;
-            return op.test(l, r);
-        }
-        return getBooleanOrDialectDefault(null, feelDialect);
-    }
-
-    /**
-     * Compares left and right for equality applying FEEL semantics to 
specific data types
-     *
-     * @param left
-     * @param right
-     * @return
-     */
-    public static Boolean isEqual(Object left, Object right, FEELDialect 
feelDialect) {
-        if (left == null || right == null) {
-            return left == right;
-        }
-
-        // spec defines that "a=[a]", i.e., singleton collections should be 
treated as the single element
-        // and vice-versa
-        if (left instanceof Collection && !(right instanceof Collection) && 
((Collection) left).size() == 1) {
-            left = ((Collection) left).toArray()[0];
-        } else if (right instanceof Collection && !(left instanceof 
Collection) && ((Collection) right).size() == 1) {
-            right = ((Collection) right).toArray()[0];
-        }
-
-        if (left instanceof Range && right instanceof Range) {
-            return isEqual((Range) left, (Range) right);
-        } else if (left instanceof Iterable && right instanceof Iterable) {
-            return isEqual((Iterable) left, (Iterable) right);
-        } else if (left instanceof Map && right instanceof Map) {
-            return isEqual((Map) left, (Map) right);
-        } else if (left instanceof ChronoPeriod && right instanceof 
ChronoPeriod) {
-            // periods have special compare semantics in FEEL as it ignores 
"days". Only months and years are compared
-            Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left);
-            Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right);
-            return isEqual(l, r, feelDialect);
-        } else if (left instanceof TemporalAccessor && right instanceof 
TemporalAccessor) {
-            // Handle specific cases when both time / datetime
-            TemporalAccessor l = (TemporalAccessor) left;
-            TemporalAccessor r = (TemporalAccessor) right;
-            if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.TIME) {
-                return isEqual(DateTimeEvalHelper.valuet(l), 
DateTimeEvalHelper.valuet(r), feelDialect);
-            } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == 
BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == 
BuiltInType.DATE_TIME) {
-                return isEqual(DateTimeEvalHelper.valuedt(l, 
r.query(TemporalQueries.zone())), DateTimeEvalHelper.valuedt(r, 
l.query(TemporalQueries.zone())), feelDialect);
-            } // fallback; continue:
-        }
-        return compare(left, right, feelDialect, (l, r) -> l.compareTo(r) == 
0);
-    }
-
     /**
      * DMNv1.2 Table 48: Specific semantics of equality
      * DMNv1.3 Table 71: Semantic of date and time functions
@@ -186,18 +78,21 @@ public class BooleanEvalHelper {
     /**
      * This method consider if the <code>value</code> object is a 
<code>String</code>
      * In that case, return the {@link String#equals(Object)} result
-     * Otherwise, default to the {@link #isEqual(Object, Object, FEELDialect)}
+     * Otherwise, default to the isEqual method
      *
      * @param value
      * @param itemFromList
-     * @return
+     * @return the boolean result based on the conditions
      */
     public static boolean isEqualsStringCompare(Object value, Object 
itemFromList) {
+        if (value == null && itemFromList == null) {
+            return true; // both null → equal
+        }
         if (value instanceof String) {
             return value.equals(itemFromList);
         } else {
             // Defaulting FEELDialect to FEEL
-            Boolean dmnEqual = isEqual(value, itemFromList, FEELDialect.FEEL);
+            Boolean dmnEqual = DefaultDialectHandler.isEqual(value, 
itemFromList, () -> null, () -> null);
             return dmnEqual != null && dmnEqual;
         }
     }
@@ -219,59 +114,31 @@ public class BooleanEvalHelper {
         return toReturn;
     }
 
-    /**
-     * Return <code>TRUE</code> if it is the original object or, depending on 
the FEELDialect, a default value
-     *
-     * @param rawReturn
-     * @param feelDialect
-     * @return
-     */
-    public static Boolean getTrueOrDialectDefault(Object rawReturn, 
FEELDialect feelDialect) {
-        if (rawReturn instanceof Boolean bool && bool) {
-            return bool;
-        } else {
-            return getBooleanOrDialectDefault(null, feelDialect);
-        }
-    }
-
-    /**
-     * Return <code>TRUE</code> if it is the original object or, depending on 
the FEELDialect, a default value
-     *
-     * @param rawReturn
-     * @param feelDialect
-     * @return
-     */
-    public static Boolean getFalseOrDialectDefault(Object rawReturn, 
FEELDialect feelDialect) {
-        if (rawReturn instanceof Boolean bool && (!bool)) {
-            return bool;
-        } else {
-            return getBooleanOrDialectDefault(null, feelDialect);
-        }
-    }
-
-    static Boolean isEqual(Range left, Range right) {
+    public static Boolean isEqual(Range left, Range right) {
         return left.equals(right);
     }
 
-    static Boolean isEqual(Iterable left, Iterable right) {
+    public static Boolean isEqual(Iterable left, Iterable right) {
         Iterator li = left.iterator();
         Iterator ri = right.iterator();
         while (li.hasNext() && ri.hasNext()) {
             Object l = li.next();
             Object r = ri.next();
-            if (!isEqualObject(l, r)) return false;
+            if (!isEqualObject(l, r))
+                return false;
         }
         return li.hasNext() == ri.hasNext();
     }
 
-    static Boolean isEqual(Map<?, ?> left, Map<?, ?> right) {
+    public static Boolean isEqual(Map<?, ?> left, Map<?, ?> right) {
         if (left.size() != right.size()) {
             return false;
         }
         for (Map.Entry le : left.entrySet()) {
             Object l = le.getValue();
             Object r = right.get(le.getKey());
-            if (!isEqualObject(l, r)) return false;
+            if (!isEqualObject(l, r))
+                return false;
         }
         return true;
     }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/DateTimeEvalHelper.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/DateTimeEvalHelper.java
index 92ae726a81..9e3f895964 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/DateTimeEvalHelper.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/DateTimeEvalHelper.java
@@ -18,13 +18,7 @@
  */
 package org.kie.dmn.feel.util;
 
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
+import java.time.*;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQueries;
@@ -36,12 +30,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class DateTimeEvalHelper {
-    public static final Logger LOG = LoggerFactory.getLogger( 
DateTimeEvalHelper.class );
+    public static final Logger LOG = 
LoggerFactory.getLogger(DateTimeEvalHelper.class);
 
     public static ZonedDateTime coerceDateTime(final LocalDate value) {
         return ZonedDateTime.of(value, LocalTime.of(0, 0, 0, 0), 
ZoneOffset.UTC);
     }
-    
+
     public static String toParsableString(TemporalAccessor temporalAccessor) {
         int hour = temporalAccessor.get(ChronoField.HOUR_OF_DAY);
         int minute = temporalAccessor.get(ChronoField.MINUTE_OF_HOUR);
@@ -51,10 +45,10 @@ public class DateTimeEvalHelper {
     }
 
     /**
-     * DMNv1.2 10.3.2.3.6 date-time, valuedt(date and time), for use in this 
{@link BooleanEvalHelper#compare(Object, Object, EvaluationContext, 
BiPredicate)}
+     * DMNv1.2 10.3.2.3.6 date-time, valuedt(date and time), for use in this 
compare method
      * DMNv1.3 also used for equality DMN13-35
      */
-     static long valuedt(TemporalAccessor datetime, ZoneId 
otherTimezoneOffset) {
+    public static long valuedt(TemporalAccessor datetime, ZoneId 
otherTimezoneOffset) {
         ZoneId alternativeTZ = 
Optional.ofNullable(otherTimezoneOffset).orElse(ZoneOffset.UTC);
         if (datetime instanceof LocalDateTime) {
             return ((LocalDateTime) 
datetime).atZone(alternativeTZ).toEpochSecond();
@@ -71,7 +65,7 @@ public class DateTimeEvalHelper {
      * DMNv1.2 10.3.2.3.4 time, valuet(time), for use in this {@link 
BooleanEvalHelper#compare(Object, Object, EvaluationContext, BiPredicate)}
      * DMNv1.3 also used for equality DMN13-35
      */
-     static long valuet(TemporalAccessor time) {
+    public static long valuet(TemporalAccessor time) {
         long result = 0;
         result += time.get(ChronoField.HOUR_OF_DAY) * (60 * 60);
         result += time.get(ChronoField.MINUTE_OF_HOUR) * (60);
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java
index 4ecfb53fa7..9e63208667 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java
@@ -18,14 +18,14 @@
  */
 package org.kie.dmn.feel.runtime.impl;
 
-import org.junit.jupiter.api.Test;
-import org.kie.dmn.feel.lang.FEELDialect;
-import org.kie.dmn.feel.runtime.Range;
-
 import java.math.BigDecimal;
 import java.time.Duration;
 import java.time.LocalDate;
 
+import org.junit.jupiter.api.Test;
+import org.kie.dmn.feel.lang.EvaluationContext;
+import org.kie.dmn.feel.runtime.Range;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 class RangeImplTest {
@@ -79,47 +79,48 @@ class RangeImplTest {
     @Test
     void includes() {
         RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, -15)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 5)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 10)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 12)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 15)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 156)).isFalse();
+        EvaluationContext ctx = null;
+        assertThat(rangeImpl.includes(null, -15)).isFalse();
+        assertThat(rangeImpl.includes(null, 5)).isFalse();
+        assertThat(rangeImpl.includes(null, 10)).isFalse();
+        assertThat(rangeImpl.includes(null, 12)).isTrue();
+        assertThat(rangeImpl.includes(null, 15)).isFalse();
+        assertThat(rangeImpl.includes(null, 156)).isFalse();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 10)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 12)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 15)).isFalse();
+        assertThat(rangeImpl.includes(null, 10)).isTrue();
+        assertThat(rangeImpl.includes(null, 12)).isTrue();
+        assertThat(rangeImpl.includes(null, 15)).isFalse();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 10)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 12)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 15)).isTrue();
+        assertThat(rangeImpl.includes(null, 10)).isFalse();
+        assertThat(rangeImpl.includes(null, 12)).isTrue();
+        assertThat(rangeImpl.includes(null, 15)).isTrue();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 10)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 12)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 15)).isTrue();
+        assertThat(rangeImpl.includes(null, 10)).isTrue();
+        assertThat(rangeImpl.includes(null, 12)).isTrue();
+        assertThat(rangeImpl.includes(null, 15)).isTrue();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), 15, Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, -1456)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 20)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, null)).isNull();
+        assertThat(rangeImpl.includes(null, -1456)).isTrue();
+        assertThat(rangeImpl.includes(null, 20)).isFalse();
+        assertThat(rangeImpl.includes(null, null)).isNull();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 15, new 
UndefinedValueComparable(), Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, -1456)).isFalse();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 20)).isTrue();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, null)).isNull();
+        assertThat(rangeImpl.includes(null, -1456)).isFalse();
+        assertThat(rangeImpl.includes(null, 20)).isTrue();
+        assertThat(rangeImpl.includes(null, null)).isNull();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, null, new 
UndefinedValueComparable(), Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, -1456)).isNull();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 20)).isNull();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, null)).isNull();
+        assertThat(rangeImpl.includes(null, -1456)).isNull();
+        assertThat(rangeImpl.includes(null, 20)).isNull();
+        assertThat(rangeImpl.includes(null, null)).isNull();
 
         rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), null, Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, -1456)).isNull();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, 20)).isNull();
-        assertThat(rangeImpl.includes(FEELDialect.FEEL, null)).isNull();
+        assertThat(rangeImpl.includes(null, -1456)).isNull();
+        assertThat(rangeImpl.includes(null, 20)).isNull();
+        assertThat(rangeImpl.includes(null, null)).isNull();
     }
 
     @Test
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BooleanEvalHelperTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BooleanEvalHelperTest.java
index 838d21aded..b7d60baf1f 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BooleanEvalHelperTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BooleanEvalHelperTest.java
@@ -18,39 +18,32 @@
  */
 package org.kie.dmn.feel.util;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Date;
-
 import org.junit.jupiter.api.Test;
 import org.kie.dmn.feel.lang.FEELDialect;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static 
org.kie.dmn.feel.util.BooleanEvalHelper.getBooleanOrDialectDefault;
-import static org.kie.dmn.feel.util.BooleanEvalHelper.getFalseOrDialectDefault;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.times;
 
 class BooleanEvalHelperTest {
 
-
-    @Test
-    void numericValuesComparative() {
-        assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 
BigDecimal.valueOf(2), FEELDialect.FEEL, (l, r) -> l.compareTo(r) < 
0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(1.0, 2.0, FEELDialect.FEEL,(l, r) 
-> l.compareTo(r) < 0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(1, 2, FEELDialect.FEEL, (l, r) -> 
l.compareTo(r) > 0)).isFalse();
-        assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 2, 
FEELDialect.FEEL,(l, r) -> l.compareTo(r) > 0)).isFalse();
-        assertThat(BooleanEvalHelper.compare(1, BigDecimal.valueOf(2), 
FEELDialect.FEEL,(l, r) -> l.compareTo(r) < 0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 2.3,  
FEELDialect.FEEL,(l, r) -> l.compareTo(r) == 0)).isFalse();
-        assertThat(BooleanEvalHelper.compare(1.2, BigDecimal.valueOf(1.2), 
FEELDialect.FEEL, (l, r) -> l.compareTo(r) == 0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 0L, 
FEELDialect.FEEL, (l, r) -> l.compareTo(r) > 0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(10L, BigDecimal.valueOf(2), 
FEELDialect.FEEL, (l, r) -> l.compareTo(r) < 0)).isFalse();
-        assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 
BigInteger.valueOf(2), FEELDialect.FEEL, (l, r) -> l.compareTo(r) == 
0)).isFalse();
-        assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 2, 
FEELDialect.FEEL, (l, r) -> l.compareTo(r) < 0)).isTrue();
-        assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 2.3,  
FEELDialect.FEEL,(l, r) -> l.compareTo(r) == 0)).isFalse();
-    }
+    //TODO Will move to FeelDialectTest clss
+    /*
+     * @Test
+     * void numericValuesComparative() {
+     * assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 
BigDecimal.valueOf(2), (l, r) -> l.compareTo(r) < 0, () -> null, () -> 
null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(1.0, 2.0, (l, r) -> l.compareTo(r) 
< 0, () -> null, () -> null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(1, 2, (l, r) -> l.compareTo(r) > 
0, () -> null, () -> null)).isFalse();
+     * assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 2, (l, r) 
-> l.compareTo(r) > 0, () -> null, () -> null)).isFalse();
+     * assertThat(BooleanEvalHelper.compare(1, BigDecimal.valueOf(2), (l, r) 
-> l.compareTo(r) < 0, () -> null, () -> null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 2.3, (l, r) 
-> l.compareTo(r) == 0, () -> null, () -> null)).isFalse();
+     * assertThat(BooleanEvalHelper.compare(1.2, BigDecimal.valueOf(1.2), (l, 
r) -> l.compareTo(r) == 0, () -> null, () -> null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(BigDecimal.valueOf(1), 0L, (l, r) 
-> l.compareTo(r) > 0, () -> null, () -> null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(10L, BigDecimal.valueOf(2), (l, r) 
-> l.compareTo(r) < 0, () -> null, () -> null)).isFalse();
+     * assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 
BigInteger.valueOf(2), (l, r) -> l.compareTo(r) == 0, () -> null, () -> 
null)).isFalse();
+     * assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 2, (l, r) 
-> l.compareTo(r) < 0, () -> null, () -> null)).isTrue();
+     * assertThat(BooleanEvalHelper.compare(BigInteger.valueOf(1), 2.3, (l, r) 
-> l.compareTo(r) == 0, () -> null, () -> null)).isFalse();
+     * }
+     */
 
     @Test
     void getBooleanOrDialectDefaultFEEL() {
@@ -68,22 +61,6 @@ class BooleanEvalHelperTest {
         assertThat(getBooleanOrDialectDefault(null, 
FEELDialect.BFEEL)).isEqualTo(Boolean.FALSE);
     }
 
-    @Test
-    void getFalseOrDialectDefaultFEEL() {
-        assertThat(getFalseOrDialectDefault(false, 
FEELDialect.FEEL)).isEqualTo(Boolean.FALSE);
-        assertThat(getFalseOrDialectDefault(true, FEELDialect.FEEL)).isNull();
-        assertThat(getFalseOrDialectDefault("true", 
FEELDialect.FEEL)).isNull();
-        assertThat(getFalseOrDialectDefault(null, FEELDialect.FEEL)).isNull();
-    }
-
-    @Test
-    void getFalseOrDialectDefaultBFEEL() {
-        assertThat(getFalseOrDialectDefault(false, 
FEELDialect.BFEEL)).isEqualTo(Boolean.FALSE);
-        assertThat(getFalseOrDialectDefault(true, 
FEELDialect.BFEEL)).isEqualTo(Boolean.FALSE);
-        assertThat(getFalseOrDialectDefault("true", 
FEELDialect.BFEEL)).isEqualTo(Boolean.FALSE);
-        assertThat(getFalseOrDialectDefault(null, 
FEELDialect.BFEEL)).isEqualTo(Boolean.FALSE);
-    }
-
     @Test
     void isEqualsSCWithStringValue() {
         assertThat(BooleanEvalHelper.isEqualsStringCompare("", "")).isTrue();
diff --git 
a/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/dtanalysis/model/Interval.java
 
b/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/dtanalysis/model/Interval.java
index d482b15290..2644be4641 100644
--- 
a/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/dtanalysis/model/Interval.java
+++ 
b/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/dtanalysis/model/Interval.java
@@ -18,16 +18,11 @@
  */
 package org.kie.dmn.validation.dtanalysis.model;
 
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import org.kie.dmn.feel.lang.FEELDialect;
+import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.runtime.Range;
 import org.kie.dmn.feel.runtime.Range.RangeBoundary;
 import org.kie.dmn.feel.runtime.impl.RangeImpl;
@@ -83,7 +78,8 @@ public class Interval {
     private Interval(Bound<?> lowerBound, Bound<?> upperBound) {
         this.lowerBound = new Bound(lowerBound.getValue(), 
lowerBound.getBoundaryType(), this);
         this.upperBound = new Bound(upperBound.getValue(), 
upperBound.getBoundaryType(), this);
-        if (lowerBound.getParent() != null && upperBound.getParent() != null 
&& lowerBound.getParent().rule == upperBound.getParent().rule && 
lowerBound.getParent().col == upperBound.getParent().col) {
+        if (lowerBound.getParent() != null && upperBound.getParent() != null 
&& lowerBound.getParent().rule == upperBound.getParent().rule
+                && lowerBound.getParent().col == upperBound.getParent().col) {
             this.rule = lowerBound.getParent().rule;
             this.col = lowerBound.getParent().col;
         } else {
@@ -108,9 +104,9 @@ public class Interval {
     @Override
     public String toString() {
         return (lowerBound.getBoundaryType() == RangeBoundary.OPEN ? "(" : 
"[") +
-               " " + Bound.boundValueToString(lowerBound.getValue()) +
-               " .. " + Bound.boundValueToString(upperBound.getValue()) +
-               " " + (upperBound.getBoundaryType() == RangeBoundary.OPEN ? ")" 
: "]");
+                " " + Bound.boundValueToString(lowerBound.getValue()) +
+                " .. " + Bound.boundValueToString(upperBound.getValue()) +
+                " " + (upperBound.getBoundaryType() == RangeBoundary.OPEN ? 
")" : "]");
     }
 
     public Bound<?> getLowerBound() {
@@ -171,13 +167,14 @@ public class Interval {
 
     public boolean asRangeIncludes(Object param) {
         // Defaulting FEELDialect to FEEL
-        Boolean result = this.asRange.includes(FEELDialect.FEEL, param);
+        EvaluationContext ctx = null;
+        Boolean result = this.asRange.includes(ctx, param);
         if (result != null) {
             return result;
         } else if (this.lowerBound.getValue() == NEG_INF &&
-                   this.lowerBound.getBoundaryType() == RangeBoundary.CLOSED &&
-                   this.upperBound.getValue() == POS_INF &&
-                   this.upperBound.getBoundaryType() == RangeBoundary.CLOSED) {
+                this.lowerBound.getBoundaryType() == RangeBoundary.CLOSED &&
+                this.upperBound.getValue() == POS_INF &&
+                this.upperBound.getBoundaryType() == RangeBoundary.CLOSED) {
             return true;
         } else {
             return false;
@@ -196,7 +193,7 @@ public class Interval {
         return thisLeftLower && oRightHigher && (chained || adj);
     }
 
-    public static Range.RangeBoundary invertBoundary(Range.RangeBoundary b) {
+    public static RangeBoundary invertBoundary(RangeBoundary b) {
         if (b == RangeBoundary.OPEN) {
             return RangeBoundary.CLOSED;
         } else if (b == RangeBoundary.CLOSED) {
@@ -250,26 +247,26 @@ public class Interval {
         List<Interval> results = new ArrayList<>();
         if (!domain.lowerBound.equals(interval.lowerBound)) {
             Interval left = new Interval(domain.lowerBound.getBoundaryType(),
-                                         domain.lowerBound.getValue(),
-                                         interval.lowerBound.getValue(),
-                                         
invertBoundary(interval.lowerBound.getBoundaryType()),
-                                         interval.rule,
-                                         interval.col);
+                    domain.lowerBound.getValue(),
+                    interval.lowerBound.getValue(),
+                    invertBoundary(interval.lowerBound.getBoundaryType()),
+                    interval.rule,
+                    interval.col);
             results.add(left);
         }
         if (!domain.upperBound.equals(interval.upperBound)) {
             Interval right = new 
Interval(invertBoundary(interval.upperBound.getBoundaryType()),
-                                          interval.upperBound.getValue(),
-                                          domain.upperBound.getValue(),
-                                          domain.upperBound.getBoundaryType(),
-                                          interval.rule,
-                                          interval.col);
+                    interval.upperBound.getValue(),
+                    domain.upperBound.getValue(),
+                    domain.upperBound.getBoundaryType(),
+                    interval.rule,
+                    interval.col);
             results.add(right);
         }
         LOG.debug("results {}", results);
         return results;
     }
-    
+
     public static List<Interval> invertOverDomain(List<Interval> intervals, 
Interval domain) {
         List<Interval> results = new ArrayList<>();
         final List<Interval> is = flatten(intervals);
@@ -281,11 +278,11 @@ public class Interval {
         Interval firstInterval = iterator.next();
         if (!domain.lowerBound.equals(firstInterval.lowerBound)) {
             Interval left = new Interval(domain.lowerBound.getBoundaryType(),
-                                         domain.lowerBound.getValue(),
-                                         firstInterval.lowerBound.getValue(),
-                                         
invertBoundary(firstInterval.lowerBound.getBoundaryType()),
-                                         firstInterval.rule,
-                                         firstInterval.col);
+                    domain.lowerBound.getValue(),
+                    firstInterval.lowerBound.getValue(),
+                    invertBoundary(firstInterval.lowerBound.getBoundaryType()),
+                    firstInterval.rule,
+                    firstInterval.col);
             results.add(left);
         }
         Interval previousInterval = firstInterval;
@@ -294,22 +291,22 @@ public class Interval {
             if 
((!previousInterval.upperBound.getValue().equals(nextInterval.lowerBound.getValue()))
                     || (previousInterval.upperBound.getBoundaryType() == 
RangeBoundary.OPEN && nextInterval.lowerBound.getBoundaryType() == 
RangeBoundary.OPEN)) {
                 Interval iNew = new 
Interval(invertBoundary(previousInterval.upperBound.getBoundaryType()),
-                                              
previousInterval.upperBound.getValue(),
-                                              
nextInterval.lowerBound.getValue(),
-                                              
invertBoundary(nextInterval.lowerBound.getBoundaryType()),
-                                              previousInterval.rule,
-                                              previousInterval.col);
+                        previousInterval.upperBound.getValue(),
+                        nextInterval.lowerBound.getValue(),
+                        
invertBoundary(nextInterval.lowerBound.getBoundaryType()),
+                        previousInterval.rule,
+                        previousInterval.col);
                 results.add(iNew);
             }
             previousInterval = nextInterval;
         }
         if (!domain.upperBound.equals(previousInterval.upperBound)) {
             Interval right = new 
Interval(invertBoundary(previousInterval.upperBound.getBoundaryType()),
-                                          
previousInterval.upperBound.getValue(),
-                                          domain.upperBound.getValue(),
-                                          domain.upperBound.getBoundaryType(),
-                                          previousInterval.rule,
-                                          previousInterval.col);
+                    previousInterval.upperBound.getValue(),
+                    domain.upperBound.getValue(),
+                    domain.upperBound.getBoundaryType(),
+                    previousInterval.rule,
+                    previousInterval.col);
             results.add(right);
         }
         LOG.debug("results {}", results);
@@ -317,21 +314,21 @@ public class Interval {
     }
 
     public String asHumanFriendly(Domain domain) {
-        if (lowerBound.getValue().equals(upperBound.getValue()) 
-                && lowerBound.getBoundaryType() == RangeBoundary.CLOSED 
+        if (lowerBound.getValue().equals(upperBound.getValue())
+                && lowerBound.getBoundaryType() == RangeBoundary.CLOSED
                 && upperBound.getBoundaryType() == RangeBoundary.CLOSED) {
             return Bound.boundValueToString(lowerBound.getValue());
         } else if (domain.isDiscreteDomain()) {
             List<?> dValues = domain.getDiscreteValues();
             int posL = dValues.indexOf(lowerBound.getValue());
             if (posL < dValues.size() - 1
-                && dValues.get(posL + 1).equals(upperBound.getValue())
-                    && lowerBound.getBoundaryType() == RangeBoundary.CLOSED 
+                    && dValues.get(posL + 1).equals(upperBound.getValue())
+                    && lowerBound.getBoundaryType() == RangeBoundary.CLOSED
                     && upperBound.getBoundaryType() == RangeBoundary.OPEN) {
                 return Bound.boundValueToString(lowerBound.getValue());
             } else if (posL == dValues.size() - 1
-                       && lowerBound.getBoundaryType() == RangeBoundary.CLOSED 
-                       && upperBound.getBoundaryType() == 
RangeBoundary.CLOSED) {
+                    && lowerBound.getBoundaryType() == RangeBoundary.CLOSED
+                    && upperBound.getBoundaryType() == RangeBoundary.CLOSED) {
                 return Bound.boundValueToString(lowerBound.getValue());
             } else {
                 return this.toString();
@@ -376,8 +373,8 @@ public class Interval {
 
     public boolean isSingularity() {
         return lowerBound.getBoundaryType() == RangeBoundary.CLOSED &&
-               upperBound.getBoundaryType() == RangeBoundary.CLOSED &&
-               BoundValueComparator.compareValueDispatchingToInf(lowerBound, 
upperBound) == 0;
+                upperBound.getBoundaryType() == RangeBoundary.CLOSED &&
+                BoundValueComparator.compareValueDispatchingToInf(lowerBound, 
upperBound) == 0;
     }
 
     public static boolean adjOrOverlap(List<Interval> intervalsA, 
List<Interval> intervalsB) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to