/******************************************************************************* * * 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.contexts; import java.util.LinkedList; import java.util.List; import org.overture.ast.definitions.AEqualsDefinition; import org.overture.ast.definitions.AExplicitFunctionDefinition; import org.overture.ast.definitions.AImplicitFunctionDefinition; import org.overture.ast.definitions.PDefinition; import org.overture.ast.expressions.AExistsExp; import org.overture.ast.expressions.AImpliesBooleanBinaryExp; import org.overture.ast.expressions.ALetDefExp; import org.overture.ast.expressions.PExp; import org.overture.ast.factory.AstExpressionFactory; import org.overture.ast.factory.AstFactory; import org.overture.ast.intf.lex.ILexNameToken; import org.overture.ast.lex.LexNameToken; import org.overture.ast.patterns.APatternTypePair; import org.overture.ast.patterns.ATypeMultipleBind; import org.overture.ast.patterns.PMultipleBind; import org.overture.ast.patterns.PPattern; import org.overture.ast.types.ABooleanBasicType; import org.overture.ast.types.AFunctionType; public class POFunctionResultContext extends POContext { public final ILexNameToken name; public final AFunctionType deftype; public final PExp precondition; public final PExp body; public final APatternTypePair result; public final boolean implicit; final PDefinition function; public POFunctionResultContext(AExplicitFunctionDefinition definition) { this.name = definition.getName(); this.deftype = (AFunctionType) definition.getType(); this.precondition = definition.getPrecondition(); this.body = definition.getBody(); this.implicit = false; this.result = AstFactory.newAPatternTypePair(AstFactory.newAIdentifierPattern(new LexNameToken(definition.getName().getModule(), "RESULT", definition.getLocation())), ((AFunctionType) definition.getType()).getResult().clone()); this.function = definition.clone(); function.setLocation(null); } public POFunctionResultContext(AImplicitFunctionDefinition definition) { this.name = definition.getName(); this.deftype = (AFunctionType) definition.getType(); this.precondition = definition.getPrecondition(); this.body = definition.getBody(); this.implicit = true; this.result = definition.getResult(); this.function = definition; } @Override public PExp getContextNode(PExp stitch) { PExp stitched = getContextNodeMain(stitch); if (precondition == null) { return stitched; } else { AImpliesBooleanBinaryExp imp = AstExpressionFactory.newAImpliesBooleanBinaryExp(precondition.clone(), stitched); return imp; } } private PExp getContextNodeMain(PExp stitch) { if (implicit) { AExistsExp exists_exp = new AExistsExp(); exists_exp.setType(new ABooleanBasicType()); List<PMultipleBind> binds = new LinkedList<PMultipleBind>(); ATypeMultipleBind tmBind = new ATypeMultipleBind(); List<PPattern> patternList = new LinkedList<PPattern>(); patternList.add(result.getPattern().clone()); tmBind.setPlist(patternList); tmBind.setType(result.getType().clone()); binds.add(tmBind); exists_exp.setBindList(binds); exists_exp.setPredicate(stitch); return exists_exp; } else { ALetDefExp letDefExp = new ALetDefExp(); AEqualsDefinition localDef = new AEqualsDefinition(); localDef.setPattern(result.getPattern().clone()); localDef.setType(result.getType().clone()); localDef.setTest(body.clone()); List<PDefinition> defs = new LinkedList<PDefinition>(); defs.add(localDef); letDefExp.setLocalDefs(defs); letDefExp.setExpression(stitch); return letDefExp; } } @Override public String getContext() { StringBuilder sb = new StringBuilder(); if (precondition != null) { sb.append(precondition); sb.append(" => "); } if (implicit) { sb.append("forall "); sb.append(result); sb.append(" & "); } else { sb.append("let "); sb.append(result); sb.append(" = "); sb.append(body); sb.append(" in "); } return sb.toString(); } }