private List<PExp> extractAssumptionsFromParameter(ProgParameterSymbol p) {
    List<PExp> resultingAssumptions = new ArrayList<>();
    if (p.getDeclaredType() instanceof ProgNamedType) {

      // both PTFamily AND PTRepresentation are a PTNamed
      ProgNamedType declaredType = (ProgNamedType) p.getDeclaredType();
      PExp exemplar = declaredType.getExemplarAsPSymbol();
      if (declaredType instanceof ProgFamilyType) {
        PExp constraint = ((ProgFamilyType) declaredType).getConstraint();

        constraint = constraint.substitute(getSpecializationsForFacility(p.getTypeQualifier()));
        resultingAssumptions.add(
            constraint.substitute(
                declaredType.getExemplarAsPSymbol(),
                p.asPSymbol())); // ASSUME TC (type constraint -- since we're conceptual)
      } else if (declaredType instanceof PTRepresentation) {
        ProgReprTypeSymbol repr = ((PTRepresentation) declaredType).getReprTypeSymbol();
        PExp convention = repr.getConvention();

        resultingAssumptions.add(
            convention.substitute(declaredType.getExemplarAsPSymbol(), p.asPSymbol()));
        // ASSUME RC (repr convention -- since we're a repr)
        resultingAssumptions.add(repr.getCorrespondence());
      }
    } else { // PTGeneric
      //    resultingAssumptions.add(g.formInitializationPredicate(
      //            p.getDeclaredType(), p.getName()));
    }
    return resultingAssumptions;
  }
  private List<PExp> extractConsequentsFromParameter(ProgParameterSymbol p) {
    List<PExp> result = new ArrayList<>();
    PExp incParamExp = new PSymbolBuilder(p.asPSymbol()).incoming(true).build();
    PExp paramExp = new PSymbolBuilder(p.asPSymbol()).incoming(false).build();

    if (p.getDeclaredType() instanceof ProgNamedType) {
      ProgNamedType t = (ProgNamedType) p.getDeclaredType();
      PExp exemplar = new PSymbolBuilder(t.getExemplarName()).mathClssfctn(t.toMath()).build();

      if (t instanceof PTRepresentation) {
        ProgReprTypeSymbol repr = ((PTRepresentation) t).getReprTypeSymbol();

        PExp convention = repr.getConvention();
        PExp corrFnExp = repr.getCorrespondence();
        result.add(convention.substitute(t.getExemplarAsPSymbol(), paramExp));
      }
      if (p.getMode() == ParameterMode.PRESERVES || p.getMode() == ParameterMode.RESTORES) {
        PExp equalsExp =
            g.formEquals(paramExp, incParamExp)
                .withVCInfo(
                    p.getDefiningTree().getStart(),
                    "Ensure parameter " + p.getName() + " is restored");
        result.add(equalsExp);
      } else if (p.getMode() == ParameterMode.CLEARS) {
        PExp init =
            ((ProgNamedType) p.getDeclaredType())
                .getInitializationEnsures()
                .substitute(exemplar, paramExp);
        result.add(init);
      }
    }
    return result;
  }
 private List<PExp> getAssertionsFromFormalParameters(
     List<ProgParameterSymbol> parameters, Function<ProgParameterSymbol, List<PExp>> extract) {
   List<PExp> result = new ArrayList<>();
   for (ProgParameterSymbol p : parameters) {
     result.addAll(extract.apply(p));
   }
   return result;
 }
 private List<PExp> getAssertionsFromModuleFormalParameters(
     List<ModuleParameterSymbol> parameters, Function<ProgParameterSymbol, List<PExp>> extract) {
   List<PExp> result = new ArrayList<>();
   for (ModuleParameterSymbol p : parameters) {
     // todo: For now.
     if (p.getWrappedParamSymbol() instanceof ProgParameterSymbol) {
       result.addAll(extract.apply((ProgParameterSymbol) p.getWrappedParamSymbol()));
     }
   }
   return result;
 }
 public List<ModuleParameterSymbol> getAllModuleParameterSyms() {
   List<ModuleParameterSymbol> result = moduleScope.getSymbolsOfType(ModuleParameterSymbol.class);
   for (ModuleIdentifier e : moduleScope.getInheritedIdentifiers()) {
     try {
       ModuleScopeBuilder s = symtab.getModuleScope(e);
       result.addAll(s.getSymbolsOfType(ModuleParameterSymbol.class));
     } catch (NoSuchModuleException e1) { // should've been caught a long time ago
       throw new RuntimeException(e1);
     }
   }
   return result;
 }
 private List<PExp> reduceArgs(List<ParserRuleContext> args) {
   List<PExp> result = new ArrayList<>();
   for (ParserRuleContext arg : args) {
     PExp argAsPExp = tr.getMathExpASTFor(g, arg);
     if (argAsPExp instanceof PApply) { // i.e., we're dealing with a function application
       PExp e = applyCallRuleToExp(arg, assertiveBlocks.peek(), (PApply) argAsPExp);
       result.add(e);
     } else {
       result.add(argAsPExp);
     }
   }
   return result;
 }
 private Set<PExp> getModuleLevelAssertionsOfType(ClauseType type) {
   Set<PExp> result = new LinkedHashSet<>();
   List<GlobalMathAssertionSymbol> assertions = new LinkedList<>();
   List<FacilitySymbol> facilities = new LinkedList<>();
   try {
     assertions.addAll(
         moduleScope
             .query(
                 new SymbolTypeQuery<GlobalMathAssertionSymbol>(GlobalMathAssertionSymbol.class))
             .stream()
             .filter(e -> e.getClauseType() == type)
             .collect(Collectors.toList()));
     facilities.addAll(
         moduleScope.query(new SymbolTypeQuery<FacilitySymbol>(FacilitySymbol.class)));
   } catch (NoSuchModuleException | UnexpectedSymbolException e) {
   }
   return assertions
       .stream()
       .map(assertion -> substituteByFacilities(facilities, assertion))
       .collect(Collectors.toSet());
 }
  @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;
  }