package com.plectix.simulator.parser.abstractmodel.reader; import java.util.ArrayList; import java.util.Collection; import java.util.List; import com.plectix.simulator.parser.DocumentFormatException; import com.plectix.simulator.parser.IncompletesDisabledException; import com.plectix.simulator.parser.KappaFileLine; import com.plectix.simulator.parser.KappaFileParagraph; import com.plectix.simulator.parser.ParseErrorException; import com.plectix.simulator.parser.ParseErrorMessage; import com.plectix.simulator.parser.abstractmodel.ModelAgent; import com.plectix.simulator.parser.abstractmodel.ModelRule; import com.plectix.simulator.parser.util.AgentFactory; import com.plectix.simulator.simulator.SimulationArguments; public final class RulesParagraphReader extends KappaParagraphReader<Collection<ModelRule>>{ private final SimulationArguments simulationArguments; public RulesParagraphReader(SimulationArguments simulationArguments, AgentFactory agentFactory) { super(simulationArguments, agentFactory); this.simulationArguments = getArguments(); } @Override public final Collection<ModelRule> readComponent( KappaFileParagraph rulesParagraph) throws ParseErrorException, DocumentFormatException { List<ModelRule> rules = new ArrayList<ModelRule>(); int ruleID = 0; boolean isStorify = simulationArguments.needToStorify(); for (KappaFileLine ruleLine : rulesParagraph. getLines()) { ruleID = fullRule(rules, ruleID, isStorify, ruleLine); } return rules; } public int fullRule(List<ModelRule> rules, int ruleID, boolean isStorify, KappaFileLine ruleLine) throws ParseErrorException, DocumentFormatException, IncompletesDisabledException { String rulesStr = ruleLine.getLine(); double activity = 1.; double activity2 = 1.; rulesStr = rulesStr.trim(); String name = null; if (rulesStr.indexOf("'") != -1) { rulesStr = rulesStr.substring(rulesStr.indexOf("'") + 1); if (rulesStr.indexOf("'") == -1) throw new ParseErrorException(ruleLine, ParseErrorMessage.UNEXPECTED_RULE_NAME, rulesStr); name = rulesStr.substring(0, rulesStr.indexOf("'")).trim(); rulesStr = rulesStr.substring(rulesStr.indexOf("'") + 1, rulesStr.length()).trim(); } double binaryRate = -1; double binaryRateOpposite = -1; int index = rulesStr.lastIndexOf("@"); if (index != -1) { try { String activStr = rulesStr.substring(index + 1).trim(); String inf = new String(new Double(Double.POSITIVE_INFINITY) .toString()); activStr = activStr.replaceAll("\\$INF", inf); if (activStr.indexOf(",") != -1) { String[] activities = activStr.split(","); // reading first part int bracketIndex = activities[0].indexOf("("); if (bracketIndex != -1) { activity = readRateInBrackets(activities[0]); activStr = activStr.substring(0, activities[0].indexOf("(")).trim(); binaryRate = Double.valueOf(activStr); } else { activity = Double.valueOf(activities[0]); } bracketIndex = activities[1].indexOf("("); if (bracketIndex != -1) { activity2 = readRateInBrackets(activities[1]); activStr = activStr.substring(0, activities[1].indexOf("(")).trim(); binaryRateOpposite = Double.valueOf(activStr); } else { activity2 = Double.valueOf(activities[1]); } // activity = Double.valueOf(activities[0]); // activity2 = Double.valueOf(activStr.substring(activStr.indexOf(",") + 1)); } else { int bracketIndex = activStr.indexOf("("); if (bracketIndex != -1) { activity = readRateInBrackets(activStr); activStr = activStr.substring(0, activStr.indexOf("(")).trim(); binaryRate = Double.valueOf(activStr); } else { activity = Double.valueOf(activStr); } } } catch (Exception e) { String details = rulesStr.substring(index).trim(); throw new ParseErrorException(ruleLine, ParseErrorMessage.UNEXPECTED_RULE_RATE, details); } rulesStr = rulesStr.substring(0, index).trim(); } index = -1; final byte RULE_TWO_WAY = 1; byte typeRule = 0; if (rulesStr.indexOf("<->") != -1) { typeRule = RULE_TWO_WAY; rulesStr = rulesStr.replace("<", ""); activity2 = simulationArguments.isForwardOnly() ? 0. : activity2; } rulesStr = rulesStr.trim(); int y = rulesStr.indexOf("->"); if (y == -1) { throw new ParseErrorException(ruleLine, ParseErrorMessage.ARROW_EXPECTED); } final byte CC_RHS = 0; final byte CC_LHS = 1; // TODO CC_ALL is never copied final byte CC_ALL = -1; if (y == 0) { index = CC_RHS; } if (y == rulesStr.length() - 2) { if (index == -1) { index = CC_LHS; } else { throw new ParseErrorException(ruleLine, ParseErrorMessage.ARROW_EXPECTED, ruleLine.getLine()); } } String[] result = rulesStr.split("\\->"); String lhs = result[0]; String rhs; if (result.length < 2) { rhs = ""; } else { rhs = result[1]; } List<ModelAgent> left = null; List<ModelAgent> right = null; String nameOp = null; if (name != null) nameOp = name + "_op"; try { switch (index) { case CC_LHS: { left = parseAgents(lhs.trim()); rules.add(new ModelRule(left, right, name, activity, binaryRate, ruleID, isStorify)); if (typeRule == RULE_TWO_WAY) { ruleID++; rules.add(new ModelRule(right, parseAgents(lhs.trim()), nameOp, activity2, binaryRateOpposite, ruleID, isStorify)); } break; } case CC_RHS: { right = parseAgents(rhs.trim()); rules.add(new ModelRule(left, right, name, activity, binaryRate, ruleID, isStorify)); if (typeRule == RULE_TWO_WAY) { ruleID++; rules.add(new ModelRule(parseAgents(rhs.trim()), left, name, activity2, binaryRateOpposite, ruleID, isStorify)); } break; } case CC_ALL: { left = parseAgents(lhs.trim()); right = parseAgents(rhs.trim()); rules.add(new ModelRule(left, right, name, activity, binaryRate, ruleID, isStorify)); if (typeRule == RULE_TWO_WAY) { ruleID++; rules.add(new ModelRule(parseAgents(rhs.trim()), parseAgents(lhs.trim()), nameOp, activity2, binaryRateOpposite, ruleID, isStorify)); } break; } } } catch (ParseErrorException e) { e.setLineDescription(ruleLine); throw e; } ruleID++; return ruleID; } /** * this method modifies it's parameter by replacing binary rate part if there's one! * @param line * @return binary rate as double */ private final double readRateInBrackets(String line) { int indexOpen = line.lastIndexOf("("); if (indexOpen != -1) { line = line.substring(indexOpen + 1); int indexClose = line.indexOf(")"); line = line.substring(0, indexClose).trim(); try { return Double.parseDouble(line); } catch(NumberFormatException e) { return -1; } } else { return -1; } } }