public SatisfiabilityObligation( AImplicitFunctionDefinition func, IPOContextStack ctxt, IPogAssistantFactory af) throws AnalysisException { super(func, POType.FUNC_SATISFIABILITY, ctxt, func.getLocation(), af); /** f: A * B -> R [pre ...] post ... [pre_f(a, b) =>] exists r:R & post_f(a, b, r) */ List<PExp> arglist = new Vector<PExp>(); for (APatternListTypePair pltp : func.getParamPatterns()) { for (PPattern pattern : pltp.getPatterns()) { arglist.add(patternToExp(pattern)); } } AApplyExp preApply = null; if (func.getPredef() != null) { preApply = getApplyExp( getVarExp(func.getPredef().getName().clone(), func.getPredef().clone()), arglist); preApply.setType(new ABooleanBasicType()); preApply.getRoot().setType(func.getPredef().getType().clone()); } AExistsExp existsExp = new AExistsExp(); existsExp.setType(new ABooleanBasicType()); List<PExp> postArglist = new Vector<PExp>(arglist); if (func.getResult().getPattern() instanceof AIdentifierPattern) { AIdentifierPattern ip = (AIdentifierPattern) func.getResult().getPattern().clone(); postArglist.add(patternToExp(func.getResult().getPattern())); existsExp.setBindList( getMultipleTypeBindList(func.getResult().getType().clone(), ip.getName())); } else { throw new RuntimeException("Expecting identifier pattern in function result"); } AApplyExp postApply = getApplyExp(getVarExp(func.getPostdef().getName(), func.getPostdef()), postArglist); postApply.setType(new ABooleanBasicType()); postApply.getRoot().setType(func.getPostdef().getType().clone()); existsExp.setPredicate(postApply); if (preApply != null) { AImpliesBooleanBinaryExp implies = AstExpressionFactory.newAImpliesBooleanBinaryExp(preApply, existsExp); stitch = implies; valuetree.setPredicate(ctxt.getPredWithContext(implies)); } else { stitch = existsExp; valuetree.setPredicate(ctxt.getPredWithContext(existsExp)); } // valuetree.setContext(ctxt.getContextNodeList()); }
PExp buildPredicate(AImplicitOperationDefinition op, PDefinition stateDefinition) throws AnalysisException { List<PExp> arglist = new Vector<PExp>(); for (APatternListTypePair pltp : op.getParameterPatterns()) { for (PPattern pattern : pltp.getPatterns()) { arglist.add(patternToExp(pattern.clone())); } } if (stateDefinition != null) { stateInPre(arglist, stateDefinition); } AApplyExp preApply = null; if (op.getPredef() != null) { preApply = getApplyExp(getVarExp(op.getPredef().getName().clone(), op.getPredef()), arglist); preApply.getRoot().setType(op.getPredef().getType().clone()); preApply.setType(new ABooleanBasicType()); } PExp mainExp; // Operation Has a Result. Add it in the post condition. if (op.getResult() != null) { AExistsExp existsExp = new AExistsExp(); existsExp.setType(new ABooleanBasicType()); List<PExp> postArglist = new Vector<PExp>(arglist); if (op.getResult().getPattern() instanceof AIdentifierPattern) { AIdentifierPattern ip = (AIdentifierPattern) op.getResult().getPattern(); postArglist.add(patternToExp(op.getResult().getPattern().clone())); if (stateDefinition != null) { if (stateDefinition instanceof AStateDefinition) { AVariableExp varExp = getVarExp(OLD_STATE_ARG); varExp.setType(((AStateDefinition) stateDefinition).getRecordType().clone()); postArglist.add(varExp); AVariableExp varExp2 = getVarExp(NEW_STATE_ARG); varExp2.setType(((AStateDefinition) stateDefinition).getRecordType().clone()); postArglist.add(varExp2); } else { AVariableExp varExp = getVarExp(OLD_SELF_ARG); postArglist.add(varExp); varExp.setType(stateDefinition.getType().clone()); AVariableExp varExp2 = getVarExp(NEW_SELF_ARG); postArglist.add(varExp2); varExp2.setType(stateDefinition.getType().clone()); } } existsExp.setBindList( getMultipleTypeBindList(op.getResult().getType().clone(), ip.getName().clone())); } else { throw new RuntimeException("Expecting single identifier pattern in operation result"); } AApplyExp postApply = getApplyExp(getVarExp(op.getPostdef().getName()), postArglist); postApply.getRoot().setType(op.getPostdef().getType().clone()); postApply.setType(new ABooleanBasicType()); existsExp.setPredicate(postApply); mainExp = existsExp; } // No Result. Just add new state to post condition else { AExistsExp exists_exp = new AExistsExp(); exists_exp.setType(new ABooleanBasicType()); List<PExp> postArglist = new Vector<PExp>(arglist); List<PMultipleBind> exists_binds = new LinkedList<PMultipleBind>(); if (stateDefinition != null) { stateInPost(exists_binds, postArglist, stateDefinition); } exists_exp.setBindList(exists_binds); AApplyExp postApply = getApplyExp(getVarExp(op.getPostdef().getName()), new Vector<PExp>(postArglist)); postApply.setType(new ABooleanBasicType()); postApply.getRoot().setType(op.getPostdef().getType().clone()); exists_exp.setPredicate(postApply); mainExp = exists_exp; } if (preApply != null) { return AstExpressionFactory.newAImpliesBooleanBinaryExp(preApply, mainExp); } else { return mainExp; } }