package org.overture.pog.visitors; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.analysis.QuestionAnswerAdaptor; import org.overture.ast.definitions.PDefinition; import org.overture.ast.expressions.ACaseAlternative; import org.overture.ast.expressions.PExp; import org.overture.ast.expressions.PModifier; import org.overture.ast.modules.AModuleModules; import org.overture.ast.modules.PExport; import org.overture.ast.modules.PExports; import org.overture.ast.modules.PImports; import org.overture.ast.modules.PModules; import org.overture.ast.node.INode; import org.overture.ast.patterns.ASeqBind; import org.overture.ast.patterns.ASeqMultipleBind; import org.overture.ast.patterns.ASetBind; import org.overture.ast.patterns.ASetMultipleBind; import org.overture.ast.patterns.ATypeBind; import org.overture.ast.patterns.ATypeMultipleBind; import org.overture.ast.patterns.PBind; import org.overture.ast.patterns.PPair; import org.overture.ast.patterns.PPattern; import org.overture.ast.patterns.PPatternBind; import org.overture.ast.statements.AMapSeqStateDesignator; import org.overture.ast.statements.ATixeStmtAlternative; import org.overture.ast.statements.PCase; import org.overture.ast.statements.PClause; import org.overture.ast.statements.PObjectDesignator; import org.overture.ast.statements.PStateDesignator; import org.overture.ast.statements.PStm; import org.overture.ast.types.PAccessSpecifier; import org.overture.ast.types.PField; import org.overture.ast.types.PType; import org.overture.pog.contexts.POCaseContext; import org.overture.pog.contexts.PONameContext; import org.overture.pog.contexts.PONotCaseContext; import org.overture.pog.obligation.ProofObligationList; import org.overture.pog.obligation.SeqApplyObligation; import org.overture.pog.pub.IPOContextStack; import org.overture.pog.pub.IPogAssistantFactory; import org.overture.pog.pub.IProofObligationList; import org.overture.pog.utility.POException; import org.overture.pog.utility.PogAssistantFactory; /** * This is the proof obligation visitor climbs through the AST and builds the list of proof obligations the given * program exhibits. References: [1] http://wiki.overturetool.org/images/9/95/VDM10_lang_man.pdf for BNF definitions. * This work is based on previous work by Nick Battle in the VDMJ package. * * @author Overture team * @param <Q> * @param <A> * @since 1.0 */ public class PogParamVisitor<Q extends IPOContextStack, A extends IProofObligationList> extends QuestionAnswerAdaptor<IPOContextStack, IProofObligationList> { private PogExpVisitor pogExpVisitor = new PogExpVisitor(this); private PogStmVisitor pogStmVisitor = new PogStmVisitor(this); private PogDefinitionVisitor pogDefinitionVisitor = new PogDefinitionVisitor(this); final private IPogAssistantFactory assistantFactory; public PogParamVisitor() { this.assistantFactory = new PogAssistantFactory(); } /** * <b>Warning!</b> This constructor is not for use with Overture extensions as it sets several customisable fields * to Overture defaults. Use {@link #PogParamVisitor(IPogAssistantFactory)} instead * * @param assistantFactory */ public PogParamVisitor(IPogAssistantFactory assistantFactory) { this.assistantFactory = assistantFactory; } @Override // See [1] pg. 167 for the definition public IProofObligationList caseAModuleModules(AModuleModules node, IPOContextStack question) throws AnalysisException { IProofObligationList ipol = new ProofObligationList(); for (PDefinition p : node.getDefs()) { question.push(new PONameContext(assistantFactory.createPDefinitionAssistant().getVariableNames(p))); ipol.addAll(p.apply(this, question)); question.pop(); question.clearStateContexts(); } return ipol; } @Override public IProofObligationList defaultPExp(PExp node, IPOContextStack question) throws AnalysisException { return node.apply(pogExpVisitor, question); } @Override public IProofObligationList defaultPModifier(PModifier node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList caseACaseAlternative(ACaseAlternative node, IPOContextStack question) throws AnalysisException { try { IProofObligationList obligations = new ProofObligationList(); question.push(new POCaseContext(node.getPattern(), node.getType(), node.getCexp(), assistantFactory)); obligations.addAll(node.getResult().apply(this.pogExpVisitor, question)); question.pop(); question.push(new PONotCaseContext(node.getPattern(), node.getType(), node.getCexp(), assistantFactory)); return obligations; } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList defaultPType(PType node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPField(PField node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPAccessSpecifier(PAccessSpecifier node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPPattern(PPattern node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPPair(PPair node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPBind(PBind node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList caseASetBind(ASetBind node, IPOContextStack question) throws AnalysisException { try { return node.getSet().apply(this.pogExpVisitor, question); } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList caseASeqBind(ASeqBind node, IPOContextStack question) throws AnalysisException { try { return node.getSeq().apply(this.pogExpVisitor, question); } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList caseASetMultipleBind(ASetMultipleBind node, IPOContextStack question) throws AnalysisException { try { return node.getSet().apply(this.pogExpVisitor, question); } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList caseASeqMultipleBind(ASeqMultipleBind node, IPOContextStack question) throws AnalysisException { try { return node.getSeq().apply(this.pogExpVisitor, question); } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList caseATypeMultipleBind(ATypeMultipleBind node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPPatternBind(PPatternBind node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPDefinition(PDefinition node, IPOContextStack question) throws AnalysisException { return node.apply(pogDefinitionVisitor, question); } @Override public IProofObligationList defaultPModules(PModules node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPImports(PImports node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPExports(PExports node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPExport(PExport node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPStm(PStm node, IPOContextStack question) throws AnalysisException { return node.apply(pogStmVisitor, question); } @Override public IProofObligationList defaultPStateDesignator(PStateDesignator node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList caseAMapSeqStateDesignator( AMapSeqStateDesignator node, IPOContextStack question) throws AnalysisException { try { IProofObligationList list = new ProofObligationList(); if (node.getSeqType() != null) { list.add(new SeqApplyObligation(node.getMapseq(), node.getExp(), question, assistantFactory)); } // Maps are OK, as you can create new map domain entries return list; } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList defaultPObjectDesignator( PObjectDesignator node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList caseATixeStmtAlternative( ATixeStmtAlternative node, IPOContextStack question) throws AnalysisException { try { IProofObligationList list = new ProofObligationList(); if (node.getPatternBind().getPattern() != null) { // Nothing to do } else if (node.getPatternBind().getBind() instanceof ATypeBind) { // Nothing to do } else if (node.getPatternBind().getBind() instanceof ASetBind) { ASetBind bind = (ASetBind) node.getPatternBind().getBind(); list.addAll(bind.getSet().apply(this.pogExpVisitor, question)); } list.addAll(node.getStatement().apply(this.pogStmVisitor, question)); return list; } catch (Exception e) { throw new POException(node, e.getMessage()); } } @Override public IProofObligationList defaultPClause(PClause node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList defaultPCase(PCase node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList createNewReturnValue(INode node, IPOContextStack question) { return new ProofObligationList(); } @Override public IProofObligationList createNewReturnValue(Object node, IPOContextStack question) { return new ProofObligationList(); } }