Browse Source
imported patch rewardcounter-TemporalOperatorBounds.patch
tud-infrastructure-2018-10-12
imported patch rewardcounter-TemporalOperatorBounds.patch
tud-infrastructure-2018-10-12
3 changed files with 315 additions and 0 deletions
-
291prism/src/parser/ast/TemporalOperatorBounds.java
-
12prism/src/parser/visitor/ASTTraverse.java
-
12prism/src/parser/visitor/ASTTraverseModify.java
@ -0,0 +1,291 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2015- |
|||
// Authors: |
|||
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden) |
|||
// |
|||
//------------------------------------------------------------------------------ |
|||
// |
|||
// This file is part of PRISM. |
|||
// |
|||
// PRISM 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 2 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// PRISM 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 PRISM; if not, write to the Free Software Foundation, |
|||
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|||
// |
|||
//============================================================================== |
|||
|
|||
package parser.ast; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Arrays; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
|
|||
import parser.visitor.ASTVisitor; |
|||
import prism.ModelType; |
|||
import prism.PrismLangException; |
|||
|
|||
/** |
|||
* A conjunction of bounds attached to a temporal operator. |
|||
* <br> |
|||
* If there is only one bound, it can be a DEFAULT_BOUND, where the |
|||
* bound type is context dependent. |
|||
*/ |
|||
public class TemporalOperatorBounds extends ASTElement { |
|||
/** The list (conjunction) of TemporalOperatorBound */ |
|||
public List<TemporalOperatorBound> bounds = new ArrayList<TemporalOperatorBound>(); |
|||
|
|||
/** Get the list of bounds */ |
|||
public List<TemporalOperatorBound> getBounds() |
|||
{ |
|||
return bounds; |
|||
} |
|||
|
|||
/** Adds the specified bound. Can only be used to add non-default bounds! */ |
|||
public void addBound(TemporalOperatorBound bound) |
|||
{ |
|||
if (bound.getBoundType() == TemporalOperatorBound.BoundType.DEFAULT_BOUND) { |
|||
throw new IllegalArgumentException("Can not add default bound!"); |
|||
} |
|||
bounds.add(bound); |
|||
} |
|||
|
|||
/** |
|||
* Sets the default bound as the only bound. It is an error if bound is not a default bound. |
|||
*/ |
|||
public void setDefaultBound(TemporalOperatorBound bound) { |
|||
if (bound.getBoundType() != TemporalOperatorBound.BoundType.DEFAULT_BOUND) { |
|||
throw new IllegalArgumentException("Can not set non-default bound as default bound!"); |
|||
} |
|||
|
|||
bounds.clear(); |
|||
bounds.add(bound); |
|||
} |
|||
|
|||
/** Get the number of bounds */ |
|||
public int countBounds() {return bounds.size();} |
|||
|
|||
/** Get the number of bounds of type TIME_BOUND */ |
|||
public int countTimeBounds() {return countBoundsOfType(TemporalOperatorBound.BoundType.TIME_BOUND);} |
|||
|
|||
/** Get the number of bounds of type STEP_BOUND */ |
|||
public int countStepBounds() {return countBoundsOfType(TemporalOperatorBound.BoundType.STEP_BOUND);} |
|||
|
|||
/** Get the number of bounds of type REWARD_BOUND */ |
|||
public int countRewardBounds() {return countBoundsOfType(TemporalOperatorBound.BoundType.REWARD_BOUND);} |
|||
|
|||
/** |
|||
* Get the number of bounds that resolve to a time bound in a discrete-time model, |
|||
* i.e., TIME_BOUND, STEP_BOUND and DEFAULT_BOUND |
|||
*/ |
|||
public int countTimeBoundsDiscrete() { |
|||
return countBoundsOfType(TemporalOperatorBound.BoundType.TIME_BOUND, |
|||
TemporalOperatorBound.BoundType.STEP_BOUND, |
|||
TemporalOperatorBound.BoundType.DEFAULT_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Get the number of bounds that resolve to a time bound in a continuous-time model, |
|||
* i.e., TIME_BOUND and DEFAULT_BOUND |
|||
*/ |
|||
public int countTimeBoundsContinuous() { |
|||
return countBoundsOfType(TemporalOperatorBound.BoundType.TIME_BOUND, |
|||
TemporalOperatorBound.BoundType.DEFAULT_BOUND); |
|||
} |
|||
|
|||
/** Is the list of bounds non-empty? */ |
|||
public boolean hasBounds() {return !bounds.isEmpty();} |
|||
|
|||
/** Are there bounds of type TIME_BOUND */ |
|||
public boolean hasTimeBounds() {return countTimeBounds() > 0;} |
|||
|
|||
/** Are there bounds of type STEP_BOUND */ |
|||
public boolean hasStepBounds() {return countStepBounds() > 0;} |
|||
|
|||
/** Are there bounds of type REWARD_BOUND */ |
|||
public boolean hasRewardBounds() {return countRewardBounds() > 0;} |
|||
|
|||
/** Do we have a bound of type DEFAULT_BOUND? */ |
|||
public boolean hasDefaultBound() {return countBoundsOfType(TemporalOperatorBound.BoundType.DEFAULT_BOUND) > 0;} |
|||
|
|||
/** |
|||
* Returns the default bound, if it exists. Otherwise, {@code null} is returned. |
|||
*/ |
|||
public TemporalOperatorBound getDefaultBound() |
|||
{ |
|||
return getFirstOfBoundType(TemporalOperatorBound.BoundType.DEFAULT_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Returns the default bound or the single time bound. |
|||
* Returns {@code null} if there is none, |
|||
* throws exception if there are multiple time bounds. |
|||
*/ |
|||
public TemporalOperatorBound getTimeBoundForContinuousTime() throws PrismLangException |
|||
{ |
|||
if (hasDefaultBound()) {return getDefaultBound();} |
|||
if (countTimeBounds() > 1) { |
|||
throw new PrismLangException("Multiple time bounds, not supported!"); |
|||
} |
|||
return getFirstOfBoundType(TemporalOperatorBound.BoundType.TIME_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Returns the default bound, the single time bound or the single step bound. |
|||
* Returns {@code null} if there is none, throws exception if there are multiple bounds. |
|||
*/ |
|||
public TemporalOperatorBound getStepBoundForDiscreteTime() throws PrismLangException |
|||
{ |
|||
if (hasDefaultBound()) {return getDefaultBound();} |
|||
if (countTimeBounds() + countStepBounds() > 1) { |
|||
throw new PrismLangException("Multiple step/time bounds, not supported!"); |
|||
} |
|||
if (hasStepBounds()) { |
|||
return getFirstOfBoundType(TemporalOperatorBound.BoundType.STEP_BOUND); |
|||
} |
|||
return getFirstOfBoundType(TemporalOperatorBound.BoundType.TIME_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Return the step bounds in a discrete time setting, |
|||
* i.e., all STEP_BOUND, TIME_BOUND and DEFAULT_BOUND. |
|||
*/ |
|||
public List<TemporalOperatorBound> getStepBoundsForDiscreteTime() throws PrismLangException |
|||
{ |
|||
return getBoundsOfType(TemporalOperatorBound.BoundType.STEP_BOUND, |
|||
TemporalOperatorBound.BoundType.TIME_BOUND, |
|||
TemporalOperatorBound.BoundType.DEFAULT_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Return the time bounds in a continuous time setting, |
|||
* i.e., all TIME_BOUND and DEFAULT_BOUND. |
|||
*/ |
|||
public List<TemporalOperatorBound> getStepBoundsForContinuousTime() throws PrismLangException |
|||
{ |
|||
return getBoundsOfType(TemporalOperatorBound.BoundType.TIME_BOUND, |
|||
TemporalOperatorBound.BoundType.DEFAULT_BOUND); |
|||
} |
|||
|
|||
/** |
|||
* Returns the standard time/step bound for the given model type, |
|||
* either from default bound or specific time / step bound. |
|||
* Throws an exception if there are more than one step/time bounds. |
|||
* @param modelType the model type |
|||
*/ |
|||
public TemporalOperatorBound getStandardBound(ModelType modelType) throws PrismLangException |
|||
{ |
|||
if (modelType.continuousTime()) { |
|||
return getTimeBoundForContinuousTime(); |
|||
} else { |
|||
return getStepBoundForDiscreteTime(); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Return the reward bounds. |
|||
*/ |
|||
public List<TemporalOperatorBound> getRewardBounds() throws PrismLangException |
|||
{ |
|||
return getBoundsOfType(TemporalOperatorBound.BoundType.REWARD_BOUND); |
|||
} |
|||
|
|||
@Override |
|||
public Object accept(ASTVisitor v) throws PrismLangException { |
|||
return v.visit(this); |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
if (hasDefaultBound()) { |
|||
return getDefaultBound().toString(); |
|||
} else { |
|||
// TODO(JK): Change format: String result = "^{"; |
|||
String result = "{"; |
|||
boolean first=true; |
|||
for (TemporalOperatorBound bound : getBounds()) { |
|||
if (!first) result+=", "; |
|||
first=false; |
|||
result+=bound.toString(); |
|||
} |
|||
result+="}"; |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public int hashCode() |
|||
{ |
|||
final int prime = 31; |
|||
int result = 1; |
|||
result = prime * result + ((bounds == null) ? 0 : bounds.hashCode()); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public boolean equals(Object obj) |
|||
{ |
|||
if (this == obj) |
|||
return true; |
|||
if (obj == null) |
|||
return false; |
|||
if (!(obj instanceof TemporalOperatorBounds)) |
|||
return false; |
|||
TemporalOperatorBounds other = (TemporalOperatorBounds) obj; |
|||
if (bounds == null) { |
|||
if (other.bounds != null) |
|||
return false; |
|||
} else if (!bounds.equals(other.bounds)) |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public TemporalOperatorBounds deepCopy() { |
|||
TemporalOperatorBounds result = new TemporalOperatorBounds(); |
|||
for (TemporalOperatorBound bound : bounds) { |
|||
result.bounds.add(bound.deepCopy()); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
/** Helper: Count the number of bounds with the specified type */ |
|||
private int countBoundsOfType(TemporalOperatorBound.BoundType... boundTypes) |
|||
{ |
|||
return getBoundsOfType(boundTypes).size(); |
|||
} |
|||
|
|||
/** Get the first bound of the given type, {@code null} if there is none. */ |
|||
public TemporalOperatorBound getFirstOfBoundType(TemporalOperatorBound.BoundType boundType) { |
|||
for (TemporalOperatorBound bound : bounds) { |
|||
if (bound.getBoundType() == boundType) { |
|||
return bound; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** Get a list of all bounds of the given types */ |
|||
public List<TemporalOperatorBound> getBoundsOfType(TemporalOperatorBound.BoundType... types) { |
|||
HashSet<TemporalOperatorBound.BoundType> typeSet = new HashSet<TemporalOperatorBound.BoundType>(Arrays.asList(types)); |
|||
ArrayList<TemporalOperatorBound> result = new ArrayList<TemporalOperatorBound>(); |
|||
|
|||
for (TemporalOperatorBound bound : getBounds()) { |
|||
if (typeSet.contains(bound.getBoundType())) { |
|||
result.add(bound); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue