@Override public void exitOperationProcedureDecl(ResolveParser.OperationProcedureDeclContext ctx) { Scope s = symtab.getScope(ctx); VCAssertiveBlockBuilder block = assertiveBlocks.pop(); List<ProgParameterSymbol> paramSyms = s.getSymbolsOfType(ProgParameterSymbol.class); PExp corrFnExpEnsures = perParameterCorrFnExpSubstitute( paramSyms, tr.getMathExpASTFor( g, ctx.ensuresClause())); // postcondition[params 1..i <-- corr_fn_exp] corrFnExpEnsures = corrFnExpEnsures.withVCInfo(ctx.getStart(), "Ensures clause of " + ctx.name.getText()); Token loc = ctx.ensuresClause() != null ? ctx.ensuresClause().getStart() : ctx.getStart(); List<PExp> paramConsequents = new ArrayList<>(); Utils.apply(paramSyms, paramConsequents, this::extractConsequentsFromParameter); // add verification statements to the assertive context/block block.stats(Utils.collect(VCRuleBackedStat.class, ctx.stmt(), stats)); // add any additional confirms from the parameters, etc for (ProgParameterSymbol p : paramSyms) { confirmParameterConsequentsForBlock(block, p); // modfies 'block' with additional confims! } // TODO: Tomorrow look at the verification statements in the assertive context for // int_do_nothing, then block.finalConfirm(corrFnExpEnsures); outputFile.addAssertiveBlock(block.build()); }
@Override public void exitTypeRepresentationDecl(ResolveParser.TypeRepresentationDeclContext ctx) { PExp constraint = g.getTrueExp(); PExp correspondence = g.getTrueExp(); if (currentTypeReprSym == null) return; correspondence = currentTypeReprSym.getCorrespondence(); if (currentTypeReprSym.getDefinition() != null) { constraint = currentTypeReprSym.getDefinition().getProgramType().getConstraint(); } VCAssertiveBlockBuilder block = assertiveBlocks.pop(); PExp newConstraint = constraint.substitute( currentTypeReprSym.exemplarAsPSymbol(), currentTypeReprSym.conceptualExemplarAsPSymbol()); newConstraint = newConstraint.withVCInfo(ctx.getStart(), "Constraint for type: " + ctx.name.getText()); block.assume(correspondence.splitIntoConjuncts()); // throw new UnsupportedOperationException("re-institute the final confirm for this dan"); block.finalConfirm(newConstraint); outputFile.addAssertiveBlock(block.build()); }
@Override public void exitProcedureDecl(ResolveParser.ProcedureDeclContext ctx) { Scope scope = symtab.getScope(ctx); List<ProgParameterSymbol> paramSyms = scope.getSymbolsOfType(ProgParameterSymbol.class); VCAssertiveBlockBuilder block = assertiveBlocks.pop(); List<ProgParameterSymbol> formalParameters = new ArrayList<>(); try { formalParameters = scope.query(new SymbolTypeQuery<ProgParameterSymbol>(ProgParameterSymbol.class)); } catch (NoSuchModuleException | UnexpectedSymbolException e) { e.printStackTrace(); } List<PExp> corrFnExps = paramSyms .stream() .filter(p -> p.getDeclaredType() instanceof PTRepresentation) .map(p -> (PTRepresentation) p.getDeclaredType()) .map(p -> p.getReprTypeSymbol().getCorrespondence()) .collect(Collectors.toList()); PExp corrFnExpEnsures = perParameterCorrFnExpSubstitute(paramSyms, currentProcOpSym.getEnsures()) .withVCInfo(ctx.getStart(), "Ensures clause of " + ctx.name.getText()); // postcondition[params 1..i <-- corr_fn_exp] List<PExp> paramConsequents = new ArrayList<>(); Utils.apply(formalParameters, paramConsequents, this::extractConsequentsFromParameter); block .stats(Utils.collect(VCRuleBackedStat.class, ctx.stmt(), stats)) .assume(corrFnExps) .confirm(ctx, g.formConjuncts(paramConsequents)) .finalConfirm(corrFnExpEnsures); outputFile.addAssertiveBlock(block.build()); currentProcOpSym = null; }
@Override public void actionPerformed(AnActionEvent e) { Project project = e.getData(PlatformDataKeys.PROJECT); if (project == null) { LOGGER.error("actionPerformed (genVCs): no project for " + e); return; } VirtualFile resolveFile = getRESOLVEFileFromEvent(e); LOGGER.info("prove actionPerformed " + (resolveFile == null ? "NONE" : resolveFile)); if (resolveFile == null) return; String title = "RESOLVE Prove"; boolean canBeCancelled = true; commitDoc(project, resolveFile); Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); if (editor == null) return; RunRESOLVEOnLanguageFile gen = new RunRESOLVEOnLanguageFile(resolveFile, project, title); MyProverListener pl = new MyProverListener(); VCOutputFile vco = generateVCs(resolveFile, editor, project); // give each action an instance of the prover listener and make Update() print the result as it // comes back produce if (vco == null) return; RESOLVEPluginController controller = RESOLVEPluginController.getInstance(project); VerifierPanel verifierPanel = controller.getVerifierPanel(); verifierPanel.createVerifierView2( vco.getFinalVCs(), pl); // TODO: maybe make this take in a list of VCs addVCGutterIcons(vco, editor, project, pl); controller.getVerifierWindow().show(null); // runProver List<String> args = new ArrayList<>(); args.add(resolveFile.getPath()); args.add("-lib"); args.add(RunRESOLVEOnLanguageFile.getContentRoot(project, resolveFile).getPath()); args.add("-prove"); RESOLVECompiler compiler = new RESOLVECompiler(args.toArray(new String[args.size()])); compiler.addProverListener(pl); // TODO: Instead of this being anon, make a separate static class and add an error listener to // 'compiler' that (make it accessible // right here though so the UI part below can stop and update remaining (unproved) vcs if the // compiler does indeed suffer some // catastrophic failure: npe, etc. Task.Backgroundable proverTask = new Task.Backgroundable(project, "Proving") { @Override public void run(@NotNull final ProgressIndicator progressIndicator) { compiler.processCommandLineTargets(); } }; ProgressManager.getInstance().run(proverTask); // TODO: Different status icons for different proof results. running = true; Task.Backgroundable task = new Task.Backgroundable(project, "Updating Presentation") { @Override public void run(@NotNull final ProgressIndicator progressIndicator) { Map<String, Boolean> processed = new HashMap<>(); for (VC vc : vco.getFinalVCs()) { processed.put(vc.getName(), false); } while (pl.vcIsProved.size() != vco.getFinalVCs().size()) { // if (proverTask.getNotificationInfo().)//TODO: Put something here that breaks out of // this if the compiler crashes.. for (VC vc : vco.getFinalVCs()) { if (pl.vcIsProved.containsKey(vc.getName()) && !processed.get(vc.getName())) { processed.put(vc.getName(), true); long dur = pl.vcMetrics.get(vc.getName()).getProofDuration(); ConditionCollapsiblePanel section = verifierPanel.vcSelectorPanel.vcTabs.get(vc.getNumber()); section.changeToFinalState( pl.vcIsProved.get(vc.getName()) ? ConditionCollapsiblePanel.State.PROVED : ConditionCollapsiblePanel.State.NOT_PROVED, dur); } } } running = false; } }; ProgressManager.getInstance().run(task); }
private void addVCGutterIcons( VCOutputFile vco, Editor editor, Project project, MyProverListener listener) { if (!editor.isDisposed()) { highlighters.clear(); MarkupModel markup = editor.getMarkupModel(); RESOLVEPluginController controller = RESOLVEPluginController.getInstance(project); markup.removeAllHighlighters(); // A mapping from [line number] -> [vc_1, .., vc_j] Map<Integer, List<VC>> byLine = vco.getVCsGroupedByLineNumber(); List<RangeHighlighter> vcRelatedHighlighters = new ArrayList<>(); for (Map.Entry<Integer, List<VC>> vcsByLine : byLine.entrySet()) { List<AnAction> actionsPerVC = new ArrayList<>(); // create clickable actions for each vc for (VC vc : vcsByLine.getValue()) { actionsPerVC.add( new VCNavigationAction(listener, vc.getNumber() + "", vc.getExplanation())); } highlighter = markup.addLineHighlighter( vcsByLine.getKey() - 1, HighlighterLayer.ELEMENT_UNDER_CARET, null); highlighter.setGutterIconRenderer( new GutterIconRenderer() { @NotNull @Override public Icon getIcon() { return RESOLVEIcons.VC; } @Override public boolean equals(Object obj) { return false; } @Override public int hashCode() { return 0; } @Override public boolean isNavigateAction() { return true; } @Nullable public ActionGroup getPopupMenuActions() { DefaultActionGroup g = new DefaultActionGroup(); g.addAll(actionsPerVC); return g; } @Nullable public AnAction getClickAction() { return null; } }); vcRelatedHighlighters.add(highlighter); highlighters.add(highlighter); } editor .getDocument() .addDocumentListener( new DocumentListener() { @Override public void beforeDocumentChange(DocumentEvent event) {} @Override public void documentChanged(DocumentEvent event) { // remove all highlighters for (RangeHighlighter h : vcRelatedHighlighters) { markup.removeHighlighter(h); } VerifierPanel verifierPanel = controller.getVerifierPanel(); controller.getVerifierWindow().hide(null); verifierPanel.revertToBaseGUI(); } }); } }