package com.cfam.ruleengine.service.impl;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 计算分支表达式 的结果, 短路效果
*/
@Service
public class ShortCircuitLogicEvaluator {
public enum ElementType {
DECISION_TREE_TRAN, LOGIC, GROUP_START, GROUP_END
}
public static class Element {
ElementType type;
String value;
public Element(ElementType type, String value) {
this.type = type;
this.value = value;
}
}
// 模拟条件计算方法
private boolean getValue(Element element) {
// 这里可以根据实际需求实现条件计算逻辑
// 例如,从数据库或缓存中获取条件结果
// 这里只是一个示例,返回随机值
System.out.println("判断了:" + element );
return false;
}
/**
* 递归计算逻辑表达式的结果
* @param elements
* @param start
* @param end
* @return
*/
public boolean evaluate(List<Element> elements, int start, int end) {
boolean leftResult = false;
String currentLogic = "OR";
int i = start;
while (i <= end) {
Element element = elements.get(i);
if (element.type == ElementType.GROUP_START) {
int groupEnd = findGroupEnd(elements, i);
leftResult = evaluate(elements, i + 1, groupEnd - 1);
i = groupEnd + 1;
} else if (element.type == ElementType.DECISION_TREE_TRAN) {
leftResult = getValue(element);
i++;
}else if(element.type == ElementType.LOGIC) {
currentLogic = element.value;
// 根据上次结果和上次逻辑符,判断是否短路
if(currentLogic.equals("AND") && !leftResult){
// 例1:a&&b 例2:a&&b&&c 例3:a&&b&&c ,在这些例子中,只要a为false,则返回false
return false;
}else if(currentLogic.equals("OR") && leftResult){
// 例1:a||b 例2:a||b&&c 例3:a||b||c ,在这些例子中,只要a为true,则返回true
return true;
}else {
// 其他情况,都要等待下一个结果 , 例如a&&b a=true, 则b=true为true, b=false为false, 例如a||b , 当a=true时,b=true为true,b=false时为true,当a=false时, b=true为true,b=false=false
// 如:a||b&&c,此时b
// 此时,应将right看做一个整体
boolean currentResult = evaluate(elements, i + 1, end);
return currentLogic.equals("OR") && !currentResult || currentResult;
}
}
}
return leftResult;
}
/**
* 找到对应的右括号
* @param elements
* @param start
* @return
*/
private int findGroupEnd(List<Element> elements, int start) {
Stack<Integer> stack = new Stack<>();
stack.push(start);
for (int i = start + 1; i < elements.size(); i++) {
Element element = elements.get(i);
if (element.type == ElementType.GROUP_START) {
stack.push(i);
} else if (element.type == ElementType.GROUP_END) {
stack.pop();
if (stack.isEmpty()) {
return i;
}
}
}
return elements.size() - 1;
}
public static void main(String[] args) {
ShortCircuitLogicEvaluator evaluator = new ShortCircuitLogicEvaluator();
// 示例逻辑表达式:(RULE1 OR RULE2) AND (RULE3 OR RULE4)
List<Element> elements = new ArrayList<>();
elements.add(new Element(ElementType.GROUP_START, "("));
elements.add(new Element(ElementType.DECISION_TREE_TRAN, "RULE1"));
elements.add(new Element(ElementType.LOGIC, "AND"));
elements.add(new Element(ElementType.DECISION_TREE_TRAN, "RULE2"));
elements.add(new Element(ElementType.GROUP_END, ")"));
elements.add(new Element(ElementType.LOGIC, "OR"));
elements.add(new Element(ElementType.GROUP_START, "("));
elements.add(new Element(ElementType.DECISION_TREE_TRAN, "RULE3"));
elements.add(new Element(ElementType.LOGIC, "OR"));
elements.add(new Element(ElementType.DECISION_TREE_TRAN, "RULE4"));
elements.add(new Element(ElementType.GROUP_END, ")"));
boolean result = evaluator.evaluate(elements, 0, elements.size() - 1);
System.out.println("逻辑表达式的结果: " + result);
// System.out.println(false || true && true );
}
}