Browse Source

Check for cyclic dependencies in system...endsystem references.

git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@8602 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Dave Parker 12 years ago
parent
commit
8611094d95
  1. 62
      prism/src/parser/ast/ModulesFile.java
  2. 6
      prism/src/parser/ast/SystemBrackets.java
  3. 5
      prism/src/parser/ast/SystemDefn.java
  4. 9
      prism/src/parser/ast/SystemFullParallel.java
  5. 6
      prism/src/parser/ast/SystemHide.java
  6. 9
      prism/src/parser/ast/SystemInterleaved.java
  7. 6
      prism/src/parser/ast/SystemModule.java
  8. 7
      prism/src/parser/ast/SystemParallel.java
  9. 7
      prism/src/parser/ast/SystemReference.java
  10. 71
      prism/src/parser/ast/SystemRename.java

62
prism/src/parser/ast/ModulesFile.java

@ -32,6 +32,7 @@ import parser.*;
import parser.visitor.*;
import prism.PrismLangException;
import prism.ModelType;
import prism.PrismUtils;
import parser.type.*;
// Class representing parsed model file
@ -337,20 +338,30 @@ public class ModulesFile extends ASTElement
}
/**
* Get a "system...endsystem" construct by its name.
* Get the index of a "system...endsystem" construct by its name (indexed from 0).
* Passing null for the name looks up an un-named construct.
* Returns null if the requested construct does not exist.
*/
public SystemDefn getSystemDefnByName(String name)
public int getSystemDefnIndex(String name)
{
int i, n;
n = systemDefns.size();
for (i = 0; i < n; i++) {
int n = systemDefns.size();
for (int i = 0; i < n; i++) {
String s = systemDefnNames.get(i);
if ((s == null && name == null) || (s != null && s.equals(name)))
return systemDefns.get(i);
return i;
}
return null;
return -1;
}
/**
* Get a "system...endsystem" construct by its name.
* Passing null for the name looks up an un-named construct.
* Returns null if the requested construct does not exist.
*/
public SystemDefn getSystemDefnByName(String name)
{
int i = getSystemDefnIndex(name);
return i == -1 ? null : getSystemDefn(i);
}
/**
@ -580,11 +591,6 @@ public class ModulesFile extends ASTElement
// Check module names
checkModuleNames();
// Get synchronising action names
getSynchNames();
// Then identify/check any references to action names
findAllActions(synchs);
// Check constant identifiers
checkConstantIdents();
// Find all instances of constants
@ -608,6 +614,12 @@ public class ModulesFile extends ASTElement
// Check "system...endsystem" constructs
checkSystemDefns();
// Get synchronising action names
// (NB: Do this *after* checking for cycles in system defns above)
getSynchNames();
// Then identify/check any references to action names
findAllActions(synchs);
// Various semantic checks
semanticCheck(this);
// Type checking
@ -860,6 +872,9 @@ public class ModulesFile extends ASTElement
private void checkSystemDefns() throws PrismLangException
{
int n = systemDefns.size();
// Check there is a most one un-named system...endsystem...
// None is ok
if (n == 0)
return;
@ -878,6 +893,29 @@ public class ModulesFile extends ASTElement
if (numUnnamed > 1)
throw new PrismLangException("There can be at most one un-named system...endsystem construct", getSystemDefn(i));
}
// Check for cyclic dependencies...
// Create boolean matrix of dependencies
// (matrix[i][j] is true if prop i contains a ref to prop j)
boolean matrix[][] = new boolean[n][n];
for (int i = 0; i < n; i++) {
SystemDefn sys = systemDefns.get(i);
Vector<String> v = new Vector<>();
sys.getReferences(v);
for (int j = 0; j < v.size(); j++) {
int k = getSystemDefnIndex(v.elementAt(j));
if (k != -1) {
matrix[i][k] = true;
}
}
}
// Check for and report dependencies
int firstCycle = PrismUtils.findCycle(matrix);
if (firstCycle != -1) {
String s = "Cyclic dependency from references in system...endsystem definition \"" + getSystemDefnName(firstCycle) + "\"";
throw new PrismLangException(s, getSystemDefn(firstCycle));
}
}
/**

6
prism/src/parser/ast/SystemBrackets.java

@ -93,6 +93,12 @@ public class SystemBrackets extends SystemDefn
operand.getSynchs(v, modulesFile);
}
@Override
public void getReferences(Vector<String> v)
{
operand.getReferences(v);
}
// Methods required for ASTElement:
@Override

5
prism/src/parser/ast/SystemDefn.java

@ -64,6 +64,11 @@ public abstract class SystemDefn extends ASTElement
* Get list of all synchronising actions _introduced_ (recursively, including descent into references).
*/
public abstract void getSynchs(Vector<String> v, ModulesFile modulesFile);
/**
* Get list of all references to other SystemDefns (recursively, but not following references).
*/
public abstract void getReferences(Vector<String> v);
}
//------------------------------------------------------------------------------

9
prism/src/parser/ast/SystemFullParallel.java

@ -115,6 +115,15 @@ public class SystemFullParallel extends SystemDefn
}
}
@Override
public void getReferences(Vector<String> v)
{
int n = getNumOperands();
for (int i = 0; i < n; i++) {
getOperand(i).getReferences(v);
}
}
// Methods required for ASTElement:
@Override

6
prism/src/parser/ast/SystemHide.java

@ -120,6 +120,12 @@ public class SystemHide extends SystemDefn
operand.getSynchs(v, modulesFile);
}
@Override
public void getReferences(Vector<String> v)
{
operand.getReferences(v);
}
// Methods required for ASTElement:
@Override

9
prism/src/parser/ast/SystemInterleaved.java

@ -115,6 +115,15 @@ public class SystemInterleaved extends SystemDefn
}
}
@Override
public void getReferences(Vector<String> v)
{
int n = getNumOperands();
for (int i = 0; i < n; i++) {
getOperand(i).getReferences(v);
}
}
// Methods required for ASTElement:
@Override

6
prism/src/parser/ast/SystemModule.java

@ -87,6 +87,12 @@ public class SystemModule extends SystemDefn
// do nothing
}
@Override
public void getReferences(Vector<String> v)
{
// do nothing
}
// Methods required for ASTElement:
@Override

7
prism/src/parser/ast/SystemParallel.java

@ -134,6 +134,13 @@ public class SystemParallel extends SystemDefn
operand2.getSynchs(v, modulesFile);
}
@Override
public void getReferences(Vector<String> v)
{
operand1.getReferences(v);
operand2.getReferences(v);
}
// Methods required for ASTElement:
@Override

7
prism/src/parser/ast/SystemReference.java

@ -91,6 +91,13 @@ public class SystemReference extends SystemDefn
}
}
@Override
public void getReferences(Vector<String> v)
{
if (!v.contains(name))
v.add(name);
}
// Methods required for ASTElement:
@Override

71
prism/src/parser/ast/SystemRename.java

@ -38,78 +38,77 @@ public class SystemRename extends SystemDefn
// Vectors for pairs of actions to be renamed
private Vector<String> from;
private Vector<String> to;
// Constructors
public SystemRename()
{
from = new Vector<String>();
to = new Vector<String>();
}
public SystemRename(SystemDefn s)
{
operand = s;
from = new Vector<String>();
to = new Vector<String>();
}
// Set methods
public void setOperand(SystemDefn s)
{
operand = s;
}
public void addRename(String s1, String s2)
{
from.addElement(s1);
to.addElement(s2);
}
public void setRename(int i, String s1, String s2)
{
from.setElementAt(s1, i);
to.setElementAt(s2, i);
}
// Get methods
public SystemDefn getOperand()
{
return operand;
}
public int getNumRenames()
{
return from.size();
}
public String getFrom(int i)
{
return from.elementAt(i);
}
public String getTo(int i)
{
return to.elementAt(i);
}
public String getNewName(String s)
{
int i;
i = from.indexOf(s);
if (i == -1) {
return s;
}
else {
return (String)to.elementAt(i);
} else {
return (String) to.elementAt(i);
}
}
// Methods required for SystemDefn (all subclasses should implement):
@Override
@SuppressWarnings("deprecation")
public void getModules(Vector<String> v)
@ -129,16 +128,17 @@ public class SystemRename extends SystemDefn
{
int i, n;
String s;
// add action names in renames
// (only look in 'to' vector because we're only
// interested in actions _introduced_)
n = getNumRenames();
for (i = 0; i < n; i++) {
s = getTo(i);
if (!(v.contains(s))) v.addElement(s);
if (!(v.contains(s)))
v.addElement(s);
}
// recurse
operand.getSynchs(v);
}
@ -148,47 +148,54 @@ public class SystemRename extends SystemDefn
{
int i, n;
String s;
// add action names in renames
// (only look in 'to' vector because we're only
// interested in actions _introduced_)
n = getNumRenames();
for (i = 0; i < n; i++) {
s = getTo(i);
if (!(v.contains(s))) v.addElement(s);
if (!(v.contains(s)))
v.addElement(s);
}
// recurse
operand.getSynchs(v, modulesFile);
}
@Override
public void getReferences(Vector<String> v)
{
operand.getReferences(v);
}
// Methods required for ASTElement:
@Override
public Object accept(ASTVisitor v) throws PrismLangException
{
return v.visit(this);
}
@Override
public String toString()
{
int i, n;
String s = "";
s = s + operand + "{";
n = getNumRenames();
for (i = 0; i < n-1; i++) {
for (i = 0; i < n - 1; i++) {
s = s + getFrom(i) + "<-" + getTo(i) + ",";
}
if (n > 0) {
s = s + getFrom(n-1) + "<-" + getTo(n-1);
s = s + getFrom(n - 1) + "<-" + getTo(n - 1);
}
s = s + "}";
return s;
}
@Override
public SystemDefn deepCopy()
{

Loading…
Cancel
Save