/* Copyright 2008, 2009, 2010 by the Oxford University Computing Laboratory This file is part of HermiT. HermiT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. HermiT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with HermiT. If not, see <http://www.gnu.org/licenses/>. */ package org.semanticweb.HermiT.monitor; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.semanticweb.HermiT.Prefixes; import org.semanticweb.HermiT.tableau.BranchingPoint; import org.semanticweb.HermiT.tableau.Node; import org.semanticweb.HermiT.tableau.ReasoningTaskDescription; import org.semanticweb.HermiT.tableau.ReasoningTaskDescription.StandardTestType; public class CountingMonitor extends TableauMonitorAdapter { private static final long serialVersionUID=-8144444618897251350L; protected long m_problemStartTime; protected long m_validationStartTime; protected int m_testNo=0; // current test protected long m_time; protected int m_numberOfBacktrackings; protected int m_numberOfNodes; protected int m_numberOfBlockedNodes; protected ReasoningTaskDescription m_reasoningTaskDescription; protected boolean m_testResult; // validated blocking protected int m_initialModelSize; protected int m_initiallyBlocked; protected int m_initiallyInvalid; protected int m_noValidations; protected long m_validationTime; // overall numbers protected final Map<String,List<TestRecord>> m_testRecords=new HashMap<String, List<TestRecord>>(); protected long m_overallTime=0; protected int m_overallNumberOfBacktrackings=0; protected int m_overallNumberOfNodes=0; protected int m_overallNumberOfBlockedNodes=0; protected int m_overallNumberOfTests=0; protected int m_overallNumberOfClashes=0; protected int m_possibleInstancesTested=0; protected int m_possibleInstancesInstances=0; // validated blocking protected int m_overallInitialModelSize=0; protected int m_overallInitiallyBlocked=0; protected int m_overallInitiallyInvalid=0; protected int m_overallNoValidations=0; protected long m_overallValidationTime=0; public void reset() { m_problemStartTime=0; m_validationStartTime=0; m_time=0; m_numberOfBacktrackings=0; m_numberOfNodes=0; m_numberOfBlockedNodes=0; m_reasoningTaskDescription=null; m_testResult=false; m_initialModelSize=0; m_initiallyBlocked=0; m_initiallyInvalid=0; m_noValidations=0; m_validationTime=0; m_testRecords.clear(); m_overallTime=0; m_overallNumberOfBacktrackings=0; m_overallNumberOfNodes=0; m_overallNumberOfBlockedNodes=0; m_overallNumberOfTests=0; m_overallNumberOfClashes=0; m_possibleInstancesTested=0; m_possibleInstancesInstances=0; m_overallInitialModelSize=0; m_overallInitiallyBlocked=0; m_overallInitiallyInvalid=0; m_overallNoValidations=0; m_overallValidationTime=0; } public void isSatisfiableStarted(ReasoningTaskDescription reasoningTaskDescription) { super.isSatisfiableStarted(reasoningTaskDescription); m_testNo++; m_reasoningTaskDescription=reasoningTaskDescription; m_overallNumberOfTests++; m_problemStartTime=System.currentTimeMillis(); m_numberOfBacktrackings=0; m_numberOfNodes=0; m_numberOfBlockedNodes=0; m_initialModelSize=0; m_initiallyBlocked=0; m_initiallyInvalid=0; m_noValidations=0; m_validationTime=0; } public void isSatisfiableFinished(ReasoningTaskDescription reasoningTaskDescription,boolean result) { super.isSatisfiableFinished(reasoningTaskDescription,result); if (reasoningTaskDescription.flipSatisfiabilityResult()) result=!result; m_testResult=result; m_time=System.currentTimeMillis()-m_problemStartTime; String messagePattern=m_reasoningTaskDescription.getMessagePattern(); List<TestRecord> records=m_testRecords.get(messagePattern); if (records==null) { records=new ArrayList<TestRecord>(); m_testRecords.put(messagePattern, records); } records.add(new TestRecord(m_time, m_reasoningTaskDescription.getTaskDescription(Prefixes.STANDARD_PREFIXES), m_testResult)); m_overallTime+=m_time; m_overallNumberOfBacktrackings+=m_numberOfBacktrackings; m_numberOfNodes=m_tableau.getNumberOfNodesInTableau()-m_tableau.getNumberOfMergedOrPrunedNodes(); Node node; node=m_tableau.getFirstTableauNode(); while (node!=null) { if (node.isActive() && node.isBlocked() && node.hasUnprocessedExistentials()) m_numberOfBlockedNodes++; node=node.getNextTableauNode(); } m_overallNumberOfNodes+=m_numberOfNodes; m_overallNumberOfBlockedNodes+=m_numberOfBlockedNodes; m_overallInitialModelSize+=m_initialModelSize; m_overallInitiallyBlocked+=m_initiallyBlocked; m_overallInitiallyInvalid+=m_initiallyInvalid; m_overallNoValidations+=m_noValidations; m_overallValidationTime+=m_validationTime; } public void backtrackToFinished(BranchingPoint newCurrentBrancingPoint) { m_numberOfBacktrackings++; } public void possibleInstanceIsInstance() { m_possibleInstancesTested++; m_possibleInstancesInstances++; } public void possibleInstanceIsNotInstance() { m_possibleInstancesTested++; } public void blockingValidationStarted() { m_noValidations++; Node node; if (m_noValidations==1) { node=m_tableau.getFirstTableauNode(); while (node!=null) { if (node.isActive()) { m_initialModelSize++; if (node.isBlocked() && node.hasUnprocessedExistentials()) { m_initiallyBlocked++; } } node=node.getNextTableauNode(); } } m_validationStartTime=System.currentTimeMillis(); } public void blockingValidationFinished(int noInvalidlyBlocked) { m_validationTime+=(System.currentTimeMillis()-m_validationStartTime); if (m_noValidations==1) m_initiallyInvalid=noInvalidlyBlocked; } // getters for test records public Set<String> getUsedMessagePatterns() { return m_testRecords.keySet(); } public List<TestRecord> getTimeSortedTestRecords(int limit) { return getTimeSortedTestRecords(limit,(String)null); } public List<TestRecord> getTimeSortedTestRecords(int limit, StandardTestType standardTestType) { return getTimeSortedTestRecords(limit, standardTestType.messagePattern); } public List<TestRecord> getTimeSortedTestRecords(int limit, String messagePattern) { List<TestRecord> filteredRecords=new ArrayList<TestRecord>();; if (messagePattern==null) { for (List<TestRecord> records : m_testRecords.values()) filteredRecords.addAll(records); } else filteredRecords=m_testRecords.get(messagePattern); Collections.sort(filteredRecords); if (limit>filteredRecords.size()) limit=filteredRecords.size(); return filteredRecords.subList(0, limit); } // getters for current test measurements public long getTime() { return m_time; } public int getNumberOfBacktrackings() { return m_numberOfBacktrackings; } public int getNumberOfNodes() { return m_numberOfNodes; } public int getNumberOfBlockedNodes() { return m_numberOfBlockedNodes; } public String getTestDescription() { return m_reasoningTaskDescription.getTaskDescription(Prefixes.STANDARD_PREFIXES); } public boolean getTestResult() { return m_testResult; } // getters for current test blocking validation measurements public int getInitialModelSize() { return m_initialModelSize; } public int getInitiallyBlocked() { return m_initiallyBlocked; } public int getInitiallyInvalid() { return m_initiallyInvalid; } public int getNoValidations() { return m_noValidations; } public long getValidationTime() { return m_validationTime; } // getters for overall measurements public long getOverallTime() { return m_overallTime; } public int getOverallNumberOfBacktrackings() { return m_overallNumberOfBacktrackings; } public int getOverallNumberOfNodes() { return m_overallNumberOfNodes; } public int getOverallNumberOfBlockedNodes() { return m_overallNumberOfBlockedNodes; } public int getOverallNumberOfTests() { return m_overallNumberOfTests; } public int getOverallNumberOfTests(StandardTestType testType) { return m_testRecords.containsKey(testType.messagePattern) ? m_testRecords.get(testType.messagePattern).size() : 0; } public int getOverallNumberOfClashes() { return m_overallNumberOfClashes; } public int getNumberOfPossibleInstancesTested() { return m_possibleInstancesTested; } public int getNumberOfPossibleInstancesInstances() { return m_possibleInstancesInstances; } // getters for overall blocking validation measurements public int getOverallInitialModelSize() { return m_overallInitialModelSize; } public int getOverallInitiallyBlocked() { return m_overallInitiallyBlocked; } public int getOverallInitiallyInvalid() { return m_overallInitiallyInvalid; } public int getOverallNoValidations() { return m_overallNoValidations; } public long getOverallValidationTime() { return m_overallValidationTime; } // getters for average measurements public long getAverageTime() { if (m_testNo==0) return m_testNo; return m_overallTime/m_testNo; } public double getAverageNumberOfBacktrackings() { if (m_testNo==0) return m_testNo; return getRounded(m_overallNumberOfBacktrackings, m_testNo); } protected double getRounded(long nominator, long denominator) { return getRounded(nominator, denominator, 2); } protected double getRounded(long nominator, long denominator, int noDecimalPlaces) { double number=(double)(nominator)/(double)denominator; int tmp=(int)((number*Math.pow(10,noDecimalPlaces))); return (tmp/Math.pow(10,noDecimalPlaces)); } public double getAverageNumberOfNodes() { if (m_testNo==0) return m_testNo; return getRounded(m_overallNumberOfNodes, m_testNo); } public double getAverageNumberOfBlockedNodes() { if (m_testNo==0) return m_testNo; return getRounded(m_overallNumberOfBlockedNodes, m_testNo); } public double getAverageNumberOfClashes() { if (m_testNo==0) return m_testNo; return getRounded(m_overallNumberOfClashes, m_testNo); } public double getPossiblesToInstances() { if (m_possibleInstancesTested==0) return 0; return getRounded(m_possibleInstancesInstances,m_possibleInstancesTested); } // getters for average blocking validation measurements public double getAverageInitialModelSize() { if (m_testNo==0) return m_testNo; return getRounded(m_overallInitialModelSize, m_testNo); } public double getAverageInitiallyBlocked() { if (m_testNo==0) return m_testNo; return getRounded(m_overallInitiallyBlocked, m_testNo); } public double getAverageInitiallyInvalid() { if (m_testNo==0) return m_testNo; return getRounded(m_overallInitiallyInvalid, m_testNo); } public double getAverageNoValidations() { if (m_testNo==0) return m_testNo; return getRounded(m_overallNoValidations, m_testNo); } public long getAverageValidationTime() { if (m_testNo==0) return m_testNo; return m_overallValidationTime/m_testNo; } public static String millisToHoursMinutesSecondsString(long millis) { long time=millis/1000; long ms=time%1000; String timeStr=String.format(String.format("%%0%dd", 3), ms)+"ms"; String format=String.format("%%0%dd", 2); long secs=time%60; if (secs>0) timeStr=String.format(format, secs)+"s"+timeStr; long mins=(time%3600)/60; if (mins>0) timeStr=String.format(format, mins)+"m"+timeStr; long hours=time/3600; if (hours>0) timeStr=String.format(format, hours)+"h"+timeStr; return timeStr; } public static class TestRecord implements Comparable<TestRecord>, Serializable { private static final long serialVersionUID = -3815493500625020183L; protected final long m_testTime; protected final String m_testDescription; protected final boolean m_testResult; public TestRecord(long testTime, String testDescription, boolean result) { m_testTime=testTime; m_testDescription=testDescription; m_testResult=result; } public int compareTo(TestRecord that) { if (this==that) return 0; int result=((Long)that.m_testTime).compareTo(m_testTime); if (result!=0) return result; else return this.m_testDescription.compareToIgnoreCase(that.m_testDescription); } public long getTestTime() { return m_testTime; } public String getTestDescription() { return m_testDescription; } public boolean getTestResult() { return m_testResult; } public String toString() { return m_testTime+" ms"+(m_testTime>1000?" ("+CountingMonitor.millisToHoursMinutesSecondsString(m_testTime)+")":"")+" for "+m_testDescription+" (result: "+m_testResult+")"; } } }