Skip to content

Commit 4008148

Browse files
author
Steffen Märcker
committed
[DAG-copy] Implement deep-copying the AST without unfolding the DAG
After certain replacements, e.g., formula substitution, the AST becomes a directed acyclic graph. On copying wewant to preserve this structure. The identification of duplicates is non-local since duplicates may appear everywhere in the AST/DAG. The implementation introduces a new visitor to keep track of duplicate nodes and makes copying a two-step process: 1. Cloning a node and its internal container types via Object::clone 2. Deep-copying AST child nodes using the visitor
1 parent 51f0d1c commit 4008148

54 files changed

Lines changed: 1212 additions & 513 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

prism/src/parser/ast/ASTElement.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
// Abstract class for PRISM language AST elements
3737

38-
public abstract class ASTElement
38+
public abstract class ASTElement implements Cloneable
3939
{
4040
// Type - default to null (unknown)
4141
protected Type type = null;
@@ -186,7 +186,39 @@ public String getEndString()
186186
/**
187187
* Perform a deep copy.
188188
*/
189-
public abstract ASTElement deepCopy();
189+
public ASTElement deepCopy()
190+
{
191+
try {
192+
return new DeepCopy().copy(this);
193+
} catch (PrismLangException e) {
194+
throw new Error(e);
195+
}
196+
}
197+
198+
/**
199+
* Perform a deep copy of all internal ASTElements using a deep copy visitor.
200+
* This method is usually called after {@code clone()} and must return the receiver.
201+
*
202+
* @param copier the copy visitor
203+
* @returns the receiver with deep-copied subcomponents
204+
* @throws PrismLangException
205+
* @see #clone()
206+
*/
207+
public abstract ASTElement deepCopy(DeepCopy copier) throws PrismLangException;
208+
209+
/**
210+
* Perform a shallow copy of the receiver and
211+
* clone all internal container, e.g., lists and vectors, too.
212+
*/
213+
@Override
214+
public ASTElement clone()
215+
{
216+
try {
217+
return (ASTElement) super.clone();
218+
} catch (CloneNotSupportedException e) {
219+
throw new InternalError("Object#clone is expected to work for Cloneable objects.", e);
220+
}
221+
}
190222

191223
// Various methods based on AST traversals (implemented using the visitor
192224
// pattern):

prism/src/parser/ast/Command.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,20 @@ public String toString()
137137
s += "] " + guard + " -> " + updates;
138138
return s;
139139
}
140-
141-
/**
142-
* Perform a deep copy.
143-
*/
144-
public ASTElement deepCopy()
140+
141+
@Override
142+
public Command deepCopy(DeepCopy copier) throws PrismLangException
143+
{
144+
guard = copier.copy(guard);
145+
updates = copier.copy(updates);
146+
147+
return this;
148+
}
149+
150+
@Override
151+
public Command clone()
145152
{
146-
Command ret = new Command();
147-
ret.setSynch(getSynch());
148-
ret.setSynchIndex(getSynchIndex());
149-
ret.setGuard(getGuard().deepCopy());
150-
ret.setUpdates((Updates)getUpdates().deepCopy());
151-
ret.setPosition(this);
152-
return ret;
153+
return (Command) super.clone();
153154
}
154155
}
155156

prism/src/parser/ast/ConstantList.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
/**
4040
* Class to store list of (defined and undefined) constants
4141
*/
42-
public class ConstantList extends ASTElement
42+
public class ConstantList extends ASTElement implements Cloneable
4343
{
4444
// Name/expression/type triples to define constants
4545
private Vector<String> names = new Vector<String>();
@@ -80,7 +80,7 @@ public void addConstant(ExpressionIdent n, Expression c, Type t)
8080
types.addElement(t);
8181
nameIdents.addElement(n);
8282
}
83-
83+
8484
public void setConstant(int i, Expression c)
8585
{
8686
constants.setElementAt(c, i);
@@ -429,21 +429,29 @@ public String toString()
429429

430430
return s;
431431
}
432-
433-
/**
434-
* Perform a deep copy.
435-
*/
436-
public ASTElement deepCopy()
432+
433+
@Override
434+
public ConstantList deepCopy(DeepCopy copier) throws PrismLangException
437435
{
438-
int i, n;
439-
ConstantList ret = new ConstantList();
440-
n = size();
441-
for (i = 0; i < n; i++) {
442-
Expression constantNew = (getConstant(i) == null) ? null : getConstant(i).deepCopy();
443-
ret.addConstant((ExpressionIdent)getConstantNameIdent(i).deepCopy(), constantNew, getConstantType(i));
444-
}
445-
ret.setPosition(this);
446-
return ret;
436+
copier.copyAll(constants);
437+
copier.copyAll(nameIdents);
438+
439+
return this;
440+
}
441+
442+
443+
@SuppressWarnings("unchecked")
444+
@Override
445+
public ConstantList clone()
446+
{
447+
ConstantList clone = (ConstantList) super.clone();
448+
449+
clone.constants = (Vector<Expression>) constants.clone();
450+
clone.nameIdents = (Vector<ExpressionIdent>) nameIdents.clone();
451+
clone.names = (Vector<String>) names.clone();
452+
clone.types = (Vector<Type>) types.clone();
453+
454+
return clone;
447455
}
448456
}
449457

prism/src/parser/ast/Declaration.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,19 @@ public String toString()
138138
return s;
139139
}
140140

141-
/**
142-
* Perform a deep copy.
143-
*/
144141
@Override
145-
public ASTElement deepCopy()
142+
public Declaration deepCopy(DeepCopy copier) throws PrismLangException
143+
{
144+
declType = copier.copy(declType);
145+
start = copier.copy(start);
146+
147+
return this;
148+
}
149+
150+
@Override
151+
public Declaration clone()
146152
{
147-
Declaration ret = new Declaration(getName(), (DeclarationType)getDeclType().deepCopy());
148-
if (getStart() != null)
149-
ret.setStart(getStart().deepCopy());
150-
ret.setPosition(this);
151-
return ret;
153+
return (Declaration) super.clone();
152154
}
153155
}
154156

prism/src/parser/ast/DeclarationArray.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import parser.type.*;
3131
import parser.visitor.ASTVisitor;
32+
import parser.visitor.DeepCopy;
3233
import prism.PrismLangException;
3334

3435
public class DeclarationArray extends DeclarationType
@@ -121,17 +122,19 @@ public String toString()
121122
return "array [" + low + ".." + high + "] of " + subtype;
122123
}
123124

124-
/**
125-
* Perform a deep copy.
126-
*/
127125
@Override
128-
public ASTElement deepCopy()
126+
public DeclarationArray deepCopy(DeepCopy copier) throws PrismLangException
127+
{
128+
low = copier.copy(low);
129+
high = copier.copy(high);
130+
subtype = copier.copy(subtype);
131+
132+
return this;
133+
}
134+
135+
@Override
136+
public DeclarationArray clone()
129137
{
130-
Expression lowCopy = (low == null) ? null : low.deepCopy();
131-
Expression highCopy = (high == null) ? null : high.deepCopy();
132-
DeclarationType subtypeCopy = (DeclarationType) subtype.deepCopy();
133-
DeclarationArray ret = new DeclarationArray(lowCopy, highCopy, subtypeCopy);
134-
ret.setPosition(this);
135-
return ret;
138+
return (DeclarationArray) super.clone();
136139
}
137140
}

prism/src/parser/ast/DeclarationBool.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import parser.type.TypeBool;
3131
import parser.visitor.ASTVisitor;
32+
import parser.visitor.DeepCopy;
3233
import prism.PrismLangException;
3334

3435
public class DeclarationBool extends DeclarationType
@@ -75,13 +76,15 @@ public String toString()
7576
return "bool";
7677
}
7778

78-
/**
79-
* Perform a deep copy.
80-
*/
81-
public ASTElement deepCopy()
79+
@Override
80+
public DeclarationBool deepCopy(DeepCopy copier) throws PrismLangException
81+
{
82+
return this;
83+
}
84+
85+
@Override
86+
public DeclarationBool clone()
8287
{
83-
DeclarationBool ret = new DeclarationBool();
84-
ret.setPosition(this);
85-
return ret;
88+
return (DeclarationBool) super.clone();
8689
}
8790
}

prism/src/parser/ast/DeclarationClock.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import parser.type.*;
3030
import parser.visitor.ASTVisitor;
31+
import parser.visitor.DeepCopy;
3132
import prism.PrismLangException;
3233

3334
public class DeclarationClock extends DeclarationType
@@ -78,14 +79,15 @@ public String toString()
7879
return "clock";
7980
}
8081

81-
/**
82-
* Perform a deep copy.
83-
*/
8482
@Override
85-
public ASTElement deepCopy()
83+
public DeclarationClock deepCopy(DeepCopy copier) throws PrismLangException
84+
{
85+
return this;
86+
}
87+
88+
@Override
89+
public DeclarationClock clone()
8690
{
87-
DeclarationClock ret = new DeclarationClock();
88-
ret.setPosition(this);
89-
return ret;
91+
return (DeclarationClock) super.clone();
9092
}
9193
}

prism/src/parser/ast/DeclarationInt.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import parser.type.*;
3131
import parser.visitor.ASTVisitor;
32+
import parser.visitor.DeepCopy;
3233
import prism.PrismLangException;
3334

3435
public class DeclarationInt extends DeclarationType
@@ -106,16 +107,18 @@ public String toString()
106107
return "[" + low + ".." + high + "]";
107108
}
108109

109-
/**
110-
* Perform a deep copy.
111-
*/
112110
@Override
113-
public ASTElement deepCopy()
111+
public DeclarationInt deepCopy(DeepCopy copier) throws PrismLangException
112+
{
113+
low = copier.copy(low);
114+
high = copier.copy(high);
115+
116+
return this;
117+
}
118+
119+
@Override
120+
public DeclarationInt clone()
114121
{
115-
Expression lowCopy = (low == null) ? null : low.deepCopy();
116-
Expression highCopy = (high == null) ? null : high.deepCopy();
117-
DeclarationInt ret = new DeclarationInt(lowCopy, highCopy);
118-
ret.setPosition(this);
119-
return ret;
122+
return (DeclarationInt) super.clone();
120123
}
121124
}

prism/src/parser/ast/DeclarationIntUnbounded.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import parser.type.*;
3030
import parser.visitor.ASTVisitor;
31+
import parser.visitor.DeepCopy;
3132
import prism.PrismLangException;
3233

3334
public class DeclarationIntUnbounded extends DeclarationType
@@ -78,14 +79,15 @@ public String toString()
7879
return "int";
7980
}
8081

81-
/**
82-
* Perform a deep copy.
83-
*/
8482
@Override
85-
public ASTElement deepCopy()
83+
public DeclarationIntUnbounded deepCopy(DeepCopy copier) throws PrismLangException
84+
{
85+
return this;
86+
}
87+
88+
@Override
89+
public DeclarationIntUnbounded clone()
8690
{
87-
DeclarationIntUnbounded ret = new DeclarationIntUnbounded();
88-
ret.setPosition(this);
89-
return ret;
91+
return (DeclarationIntUnbounded) super.clone();
9092
}
9193
}

prism/src/parser/ast/DeclarationType.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,10 @@ public abstract class DeclarationType extends ASTElement
3333
* Return the default start value for a variable of this type.
3434
*/
3535
public abstract Expression getDefaultStart();
36+
37+
@Override
38+
public DeclarationType clone()
39+
{
40+
return (DeclarationType) super.clone();
41+
}
3642
}

0 commit comments

Comments
 (0)