/*******************************************************************************
*
* 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.expressions.AApplyExp;
import org.overture.ast.expressions.AForAllExp;
import org.overture.ast.expressions.AGreaterNumericBinaryExp;
import org.overture.ast.expressions.AImpliesBooleanBinaryExp;
import org.overture.ast.expressions.AStarStarBinaryExp;
import org.overture.ast.expressions.PExp;
import org.overture.ast.factory.AstExpressionFactory;
import org.overture.ast.intf.lex.ILexNameToken;
import org.overture.ast.lex.LexNameToken;
import org.overture.ast.patterns.PMultipleBind;
import org.overture.pog.pub.IPOContextStack;
import org.overture.pog.pub.IPogAssistantFactory;
import org.overture.pog.pub.POType;
public class FuncIterationObligation extends ProofObligation
{
/**
* VDM Bits: f: nat -> nat1 f(a) == a + 1 pre a < 10; g: nat -> nat g(n) == (f ** n)(0); Generate PO: (forall n:nat
* & n > 1 => forall arg:nat & pre_f(arg) => pre_f(f(arg)))
*/
private static final long serialVersionUID = -6041213040266345023L;
public FuncIterationObligation(AStarStarBinaryExp exp,
ILexNameToken preName, IPOContextStack ctxt,
IPogAssistantFactory assistantFactory) throws AnalysisException
{
super(exp, POType.FUNC_ITERATION, ctxt, exp.getLocation(), assistantFactory);
// n > 1
AGreaterNumericBinaryExp gTExp = AstExpressionFactory.newAGreaterNumericBinaryExp(exp.getRight().clone(), getIntLiteral(1));
// forall n :T & P(X)
AForAllExp forAllExp = new AForAllExp();
ILexNameToken arg = getUnique("arg");
List<PMultipleBind> bindList = getMultipleTypeBindList(assistantFactory.createPTypeAssistant().getNumeric(exp.getRight().getType().clone()), arg);
forAllExp.setBindList(bindList);
forAllExp.setPredicate(getPredicate(exp.clone(), preName.clone(), arg));
// n > 1 => forall n :T & P(X)
AImpliesBooleanBinaryExp impliesExp = AstExpressionFactory.newAImpliesBooleanBinaryExp(gTExp, forAllExp);
stitch = impliesExp.clone();
valuetree.setPredicate(ctxt.getPredWithContext(impliesExp));
}
PExp getImplies(PExp preExp, PExp leftExp, ILexNameToken preName,
ILexNameToken arg)
{
// pre_f(a)
AApplyExp pre_exp = getApplyExp(preExp, getVarExp(arg));
// f(a)
AApplyExp left_exp = getApplyExp(leftExp, getVarExp(arg));
// pre_f(f(a))
AApplyExp preleft_exp = getApplyExp(pre_exp, left_exp);
// pre_f(a) => pre_f(f(a))
AImpliesBooleanBinaryExp impliesExp = AstExpressionFactory.newAImpliesBooleanBinaryExp(pre_exp, preleft_exp);
return impliesExp;
}
private PExp getPredicate(AStarStarBinaryExp exp, ILexNameToken preName,
ILexNameToken arg)
{
if (preName != null)
{
return getImplies(getVarExp(preName), exp.getLeft(), preName, arg);
} else
{ // if no existing pre_f, build it
AApplyExp applyExp = new AApplyExp();
ILexNameToken prename = new LexNameToken("", "pre_", null);
applyExp.setRoot(getVarExp(prename));
List<PExp> argList = new LinkedList<PExp>();
argList.add(exp.getLeft());
applyExp.setArgs(argList);
return getImplies(applyExp, exp.getLeft(), prename, arg);
}
}
}