diff --git a/pom.xml b/pom.xml index 5287715..e51662e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ ee.tkasekamp ltlminer - 1.0.1 + 1.1.0 jar LTLMiner diff --git a/src/main/java/ee/tkasekamp/ltlminer/LTLMiner.java b/src/main/java/ee/tkasekamp/ltlminer/LTLMiner.java index 70da138..ccc7bf4 100644 --- a/src/main/java/ee/tkasekamp/ltlminer/LTLMiner.java +++ b/src/main/java/ee/tkasekamp/ltlminer/LTLMiner.java @@ -32,6 +32,7 @@ public class LTLMiner { private RuleCreator ruleCreator; private LTLChecker checker; private LogFilter logFilter; + private double minSupport = 0.0; public LTLMiner() { ruleCreator = new RuleCreator(); @@ -40,29 +41,50 @@ public LTLMiner() { } public ArrayList mine(XLog log, ArrayList ruleTemplates, - double threshold) { + double minSupport) { + this.minSupport = minSupport; ArrayList events = logFilter.getAllEvents(log); ArrayList rules = ruleCreator.generateRules(ruleTemplates, events); Object[] objList = checkRules(log, rules); - return filter(objList, threshold); + return filter(objList); } public ArrayList mineWithEventTypes(XLog log, - ArrayList ruleTemplates, double threshold) { + ArrayList ruleTemplates, double minSupport) { + this.minSupport = minSupport; ArrayList events = logFilter.getAllEvents(log); ArrayList eventTypes = logFilter.getEventTypes(log); ArrayList rules = ruleCreator.generateRules(ruleTemplates, events, eventTypes); Object[] objList = checkRules(log, rules); - return filter(objList, threshold); + return filter(objList); } - + public ArrayList mine(XLog log, Properties properties) { - // TODO - return null; + this.minSupport = Double.parseDouble(properties + .getProperty("minSupport")); + String queries = properties.getProperty("queries"); + ArrayList ruleTemplates = RuleTemplateCreator + .createTemplates(queries); + + boolean considerEventTypes = Boolean.parseBoolean(properties + .getProperty("considerEventTypes")); + + ArrayList events = logFilter.getAllEvents(log); + ArrayList rules; + + if (considerEventTypes) { + ArrayList eventTypes = logFilter.getEventTypes(log); + rules = ruleCreator + .generateRules(ruleTemplates, events, eventTypes); + } else { + rules = ruleCreator.generateRules(ruleTemplates, events); + } + Object[] objList = checkRules(log, rules); + return filter(objList); } private Object[] checkRules(XLog log, ArrayList rules) { @@ -86,22 +108,19 @@ private void addRulesToChecker(ArrayList rules) { /** * Gets {@link RuleModel} from {@link CheckResultObject} and returns the - * ones with coverage greater or equal to the threshold. + * ones with coverage greater or equal to the minSupport. * * @param objList * {@link Object} array containing {@link CheckResultObject} - * @param threshold - * double * @return */ - private static ArrayList filter(Object[] objList, - double threshold) { + private ArrayList filter(Object[] objList) { CheckResultObject output = (CheckResultObject) objList[0]; ArrayList result = new ArrayList<>(); for (RuleModel r : output.getRules()) { // TODO double comparison isn't good. Do with delta - if (r.getCoverage() >= threshold) { + if (r.getCoverage() >= minSupport) { result.add(r); } diff --git a/src/main/java/ee/tkasekamp/ltlminer/LTLMinerStarter.java b/src/main/java/ee/tkasekamp/ltlminer/LTLMinerStarter.java index b74417f..27d97da 100644 --- a/src/main/java/ee/tkasekamp/ltlminer/LTLMinerStarter.java +++ b/src/main/java/ee/tkasekamp/ltlminer/LTLMinerStarter.java @@ -1,8 +1,11 @@ package ee.tkasekamp.ltlminer; +import java.io.BufferedWriter; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Properties; @@ -30,6 +33,17 @@ public LTLMinerStarter(Properties properties) { public void mine() throws Exception { XLog log = readLogFile(config.getProperty("logPath")); ArrayList output = miner.mine(log, config); + String asd = config.getProperty("outputFormat"); + switch (asd) { + case "console": + printToConsole(output); + break; + case "text": + saveToFile(output, config.getProperty("outputPath")); + break; + default: + break; + } } private Properties loadProperties(String propFileName) throws IOException { @@ -49,4 +63,27 @@ private Properties loadProperties(String propFileName) throws IOException { private XLog readLogFile(String logPath) throws Exception { return XLogReader.openLog(logPath); } + + private void printToConsole(ArrayList output) { + System.out.println("coverage\tLTLRule"); + for (RuleModel ruleModel : output) { + System.out.println(ruleModel.getCoverage() + "\t" + + ruleModel.getLtlRule()); + } + } + + public void saveToFile(ArrayList output, String outputPath) { + try { + BufferedWriter out = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(outputPath), "UTF-8")); + for (RuleModel ruleModel : output) { + out.write(ruleModel.getCoverage() + "\t" + + ruleModel.getLtlRule() + "\n"); + } + out.close(); + } catch (IOException e) { + System.err.println("Couldn't save to file: " + outputPath); + } + + } } diff --git a/src/main/java/ee/tkasekamp/ltlminer/RuleTemplateCreator.java b/src/main/java/ee/tkasekamp/ltlminer/RuleTemplateCreator.java new file mode 100644 index 0000000..955d939 --- /dev/null +++ b/src/main/java/ee/tkasekamp/ltlminer/RuleTemplateCreator.java @@ -0,0 +1,75 @@ +package ee.tkasekamp.ltlminer; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RuleTemplateCreator { + private static Pattern queryParameter = Pattern.compile("\\?(\\w+)"); + + public static ArrayList createTemplates(String queries) { + ArrayList templates = new ArrayList<>(); + + String[] s = queries.split(","); + for (String string : s) { + templates.add(bla(string)); + } + return templates; + } + + private static String bla(String thing) { + thing = thing.replaceAll("\"", ""); + + HashSet a = getParameters(thing); + + thing = doSomething(thing); + return makeProper(thing, a); + + } + + private static String makeProper(String thing, HashSet parameters) { + StringBuilder s = new StringBuilder(); + + s.append("formula rule("); + for (String string : parameters) { + s.append(string + ": activity,"); + } + if (parameters.size() != 0) { + s.deleteCharAt(s.lastIndexOf(",")); + } + s.append(") := {} \n"); + s.append(thing); + s.append(";"); + + return s.toString(); + } + + private static HashSet getParameters(String query) { + Matcher m = queryParameter.matcher(query); + HashSet asasdf = new HashSet<>(); + + while (m.find()) { + String parameter = m.group(1); + asasdf.add(parameter); + + } + + return asasdf; + } + + private static String doSomething(String query) { + Matcher m = queryParameter.matcher(query); + + StringBuffer sb = new StringBuffer(query.length()); + + while (m.find()) { + String parameter = m.group(1); + String text = "activity == " + parameter; + m.appendReplacement(sb, Matcher.quoteReplacement(text)); + + } + m.appendTail(sb); + return sb.toString(); + } +} diff --git a/src/test/java/ee/tkasekamp/ltlminer/LTLMinerTest.java b/src/test/java/ee/tkasekamp/ltlminer/LTLMinerTest.java deleted file mode 100644 index 6754b0c..0000000 --- a/src/test/java/ee/tkasekamp/ltlminer/LTLMinerTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package ee.tkasekamp.ltlminer; - -import static org.junit.Assert.*; - -import org.deckfour.xes.model.XLog; -import org.junit.Before; -import org.junit.Test; - -import ee.tkasekamp.ltlminer.util.XLogReader; - -public class LTLMinerTest { - LTLMiner miner; - XLog log; - - @Before - public void setUp() throws Exception { - miner = new LTLMiner(); - log = XLogReader.openLog("src/test/resources/exercise1.xes"); - } - -} diff --git a/src/test/java/ee/tkasekamp/ltlminer/RuleTemplateCreatorTest.java b/src/test/java/ee/tkasekamp/ltlminer/RuleTemplateCreatorTest.java new file mode 100644 index 0000000..db41f6c --- /dev/null +++ b/src/test/java/ee/tkasekamp/ltlminer/RuleTemplateCreatorTest.java @@ -0,0 +1,25 @@ +package ee.tkasekamp.ltlminer; + +import static org.junit.Assert.*; + +import java.util.ArrayList; + +import org.junit.Before; +import org.junit.Test; + +public class RuleTemplateCreatorTest { + + @Test + public void test() { + + String queries = "\"[]( (?x) -> <>(?y))\", \"<>(?x)\", \"[]( (?x) -> <>(?y)\" , \"[]( (?x) -> <>(?y)\""; + + ArrayList templates = RuleTemplateCreator + .createTemplates(queries); + // for (String string : templates) { + // System.out.println(string); + // } + assertEquals(4, templates.size()); + } + +} diff --git a/src/test/java/ee/tkasekamp/ltlminer/StarterTest.java b/src/test/java/ee/tkasekamp/ltlminer/StarterTest.java new file mode 100644 index 0000000..91dab54 --- /dev/null +++ b/src/test/java/ee/tkasekamp/ltlminer/StarterTest.java @@ -0,0 +1,40 @@ +package ee.tkasekamp.ltlminer; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.Properties; + +import org.junit.Test; + +public class StarterTest { + + @Test + public void test() throws Exception { + LTLMinerStarter starter = new LTLMinerStarter(getProps()); + starter.mine(); + } + + @Test + public void test2() throws Exception { + Properties props = getProps(); + props.setProperty("outputFormat", "text"); + props.setProperty("outputPath", "rules.txt"); + LTLMinerStarter starter = new LTLMinerStarter(props); + starter.mine(); + assertTrue(new File("rules.txt").exists()); + } + + private Properties getProps() { + Properties props = new Properties(); + props.setProperty("logPath", "src/test/resources/exercise1.xes"); + props.setProperty("considerEventTypes", "true"); + props.setProperty("minSupport", "0.5"); + props.setProperty("outputFormat", "console"); + String queries = "\"[](( (?x) -> <>(?y)))\", \"<>(?x)\""; + props.setProperty("queries", queries); + + return props; + } + +}