package ftp.design; import java.io.IOException; import java.util.List; import java.util.Map; import org.cs3.prolog.connector.Connector; import org.cs3.prolog.connector.process.PrologProcess; import org.cs3.prolog.connector.process.PrologProcessException; import org.eclipse.emf.common.util.EList; import ftp.AndGate; import ftp.FTNode; import ftp.Fault; import ftp.FaultTree; import ftp.FtpFactory; import ftp.FtpPackage; import ftp.Observation; import ftp.OrGate; import ftp.Port; import ftp.PortValue; import ftp.RootEvent; import ftp.impl.Predicate; public class FTPServices { public FaultTree deriveFaultTree(Observation obs) { if (obs.getComponent() == null || obs.getPortValues() == null || (obs.getPortValues() != null && obs.getPortValues().isEmpty())) { return null; } StringBuffer query = new StringBuffer(); query.append("use_module(library(clpr)),"); // NEED TO RELATIVIZE THIS REFERENCE ... //************************************************************* query.append("consult('/Users/Mac/workspace-prolog/FTA/CertWare/fault_trees.pl'),"); //************************************************************* // assert all of the predicate definitions List<Predicate> preds = obs.getComponent().translateToLogic(); for (Predicate p : preds) { List<String> clauses = p.clauses; for (String c : clauses) { query.append("assertz(" + c + "),"); } } //translate PortValues to min_fault_tree query query.append("min_fault_tree("); query.append(obs.getComponent().getType() + "("); List<Port> ports = obs.getComponent().retrievePorts(); EList<PortValue> pvs = obs.getPortValues(); int number_of_args = 0; for (Port p : ports) { if (number_of_args > 0) query.append(","); boolean found = false; for (PortValue pv : pvs) { if (pv.getPort().equals(p)) { query.append(pv.getValue()); found = true; break; } } if (!found) { query.append("_"); } number_of_args++; } query.append(",State),State,Tree)."); // execute query in a Prolog process Map<String, Object> result = null; PrologProcess prolog = null; try { // NEED TO PARAMATERIZE THE SWIPL EXECUTABLE ... //************************************************************* prolog = Connector.newPrologProcess("/applications/swi-prolog.app/contents/macos/swipl"); //************************************************************* result = prolog.queryOnce(query.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (PrologProcessException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { prolog.stop(); } catch (PrologProcessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // Initialize the model FtpPackage.eINSTANCE.eClass(); // Retrieve the default factory singleton FtpFactory factory = FtpFactory.eINSTANCE; // build the root event RootEvent root = factory.createRootEvent(); StringBuffer sb = new StringBuffer(); if (result == null) { sb.append("NO FAULT STATES ARE COMPATIBLE WITH "); } sb.append(obs.getComponent().getType()); sb.append(':'); for (PortValue pv : pvs) { sb.append(' '); sb.append(pv.getPort().getType()); sb.append(" = "); sb.append(pv.getValue()); sb.append(','); } sb.deleteCharAt(sb.length()-1); root.setObservation(sb.toString()); FaultTree ft = factory.createFaultTree(); ft.getFtnodes().add(root); ft.setRoot(root); if (result != null) { // parse Prolog string building Java objects String term = new String(result.get("Tree").toString()); SubTree subtree = buildSubTree(term, 0, factory, ft); root.getInputs().add(subtree.faultTree); } return ft; } private SubTree buildSubTree(String root, int start, FtpFactory factory, FaultTree ft) { int next; FTNode ftnode; EList<FTNode> inputs; if (root.indexOf("or",start) == start) { OrGate or = factory.createOrGate(); inputs = or.getInputs(); ftnode = or; next = start+3; } else if (root.indexOf("and",start) == start) { AndGate and = factory.createAndGate(); inputs = and.getInputs(); ftnode = and; next = start+4; } else if (root.indexOf("fault",start) == start) { Fault fault = factory.createFault(); int begin = start+7; // start after opening "fault('" int end = root.indexOf('\'', begin); fault.setDescription(root.substring(begin, end)); ft.getFtnodes().add(fault); return new SubTree(fault,end+2); // after "')" } else return null; while (root.charAt(next) != ')') { if (root.charAt(next) == ',') next++; SubTree st = buildSubTree(root, next, factory, ft); inputs.add(st.faultTree); next = st.next; } ft.getFtnodes().add(ftnode); return new SubTree(ftnode,next+1); } private class SubTree { FTNode faultTree; int next; SubTree(FTNode ft, int i) { faultTree = ft; next = i; } } }