/*******************************************************************************
*
* Copyright (C) 2008 Fujitsu Services Ltd.
*
* Author: Nick Battle
*
* This file is part of VDMJ.
*
* VDMJ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VDMJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
package org.overture.pog.obligation;
import java.util.LinkedList;
import java.util.List;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.definitions.AExplicitFunctionDefinition;
import org.overture.ast.definitions.AImplicitFunctionDefinition;
import org.overture.ast.expressions.AApplyExp;
import org.overture.ast.expressions.ANotYetSpecifiedExp;
import org.overture.ast.expressions.ASubclassResponsibilityExp;
import org.overture.ast.expressions.AVariableExp;
import org.overture.ast.expressions.PExp;
import org.overture.ast.factory.AstExpressionFactory;
import org.overture.ast.patterns.PPattern;
import org.overture.ast.types.ABooleanBasicType;
import org.overture.pog.pub.IPOContextStack;
import org.overture.pog.pub.IPogAssistantFactory;
import org.overture.pog.pub.POType;
public class FunctionPostCondition extends ProofObligation
{
/**
*
*/
private static final long serialVersionUID = 1L;
public FunctionPostCondition(AExplicitFunctionDefinition func,
IPOContextStack ctxt, IPogAssistantFactory assistantFactory)
throws AnalysisException
{
super(func, POType.FUNC_POST_CONDITION, ctxt, func.getLocation(), assistantFactory);
List<PExp> params = new LinkedList<PExp>();
for (List<PPattern> pl : func.getParamPatternList())
{
for (PPattern p : pl)
{
params.add(patternToExp(p));
}
}
PExp body = null;
// String body = null;
if (func.getBody() instanceof ANotYetSpecifiedExp
|| func.getBody() instanceof ASubclassResponsibilityExp)
{
AApplyExp applyExp = new AApplyExp();
applyExp.setArgs(params);
AVariableExp varExp = getVarExp(func.getName().clone(), func.clone(), func.getType().clone());
applyExp.setRoot(varExp);
// We have to say "f(a)" because we have no expression yet
// I suppose this still still holds true with ast pos
body = applyExp;
} else
{
body = func.getBody();
}
PExp pred = generatePredicate(func.getPredef(), func.getPostdef().clone(), params, body);
stitch = pred;
valuetree.setPredicate(ctxt.getPredWithContext(pred));
}
public FunctionPostCondition(AImplicitFunctionDefinition func,
IPOContextStack ctxt, IPogAssistantFactory assistantFactory)
throws AnalysisException
{
super(func, POType.FUNC_POST_CONDITION, ctxt, func.getLocation(), assistantFactory);
List<PExp> params = new LinkedList<PExp>();
for (List<PPattern> pl : assistantFactory.createAImplicitFunctionDefinitionAssistant().getParamPatternList(func))
{
for (PPattern p : pl)
{
params.add(patternToExp(p));
}
}
PExp body = null;
// implicit body is apparently allowed
if (func.getBody() == null)
{
body = patternToExp(func.getResult().getPattern());
} else if (func.getBody() instanceof ANotYetSpecifiedExp
|| func.getBody() instanceof ASubclassResponsibilityExp)
{
AApplyExp applyExp = new AApplyExp();
applyExp.setArgs(params);
AVariableExp varExp = getVarExp(func.getName().clone(), func.clone(), func.getType().clone());
applyExp.setRoot(varExp);
body = applyExp;
} else
{
body = func.getBody().clone();
}
// valuetree.setContext(ctxt.getContextNodeList());
PExp pred = generatePredicate(func.getPredef(), func.getPostdef(), cloneListPExp(params), body);
stitch = pred;
valuetree.setPredicate(ctxt.getPredWithContext(pred));
}
private PExp generatePredicate(AExplicitFunctionDefinition predef,
AExplicitFunctionDefinition postdef, List<PExp> params, PExp body)
{
if (predef != null)
{
// pre(params) =>
AApplyExp applyExp = new AApplyExp();
applyExp.setType(new ABooleanBasicType());
applyExp.setArgs(cloneListPExp(params));
AVariableExp varExp = getVarExp(predef.getName().clone());
varExp.setType(predef.getType().clone());
applyExp.setRoot(varExp);
return AstExpressionFactory.newAImpliesBooleanBinaryExp(applyExp, generateBody(postdef, params, body));
}
return generateBody(postdef, params, body);
}
private PExp generateBody(AExplicitFunctionDefinition postdef,
List<PExp> params, PExp body)
{
// post(params, body)
AApplyExp applyExp = new AApplyExp();
applyExp.setType(new ABooleanBasicType());
AVariableExp varExp = getVarExp(postdef.getName());
varExp.setType(postdef.getType().clone());
applyExp.setRoot(varExp);
List<PExp> args = params;
args.add(body.clone());
applyExp.setArgs(args);
return applyExp;
}
}