|
@@ -1,16 +1,24 @@
|
|
package bk;
|
|
package bk;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
|
|
import javax.swing.JTree;
|
|
import javax.swing.JTree;
|
|
|
|
|
|
import animation.AlgorithmStage;
|
|
import animation.AlgorithmStage;
|
|
|
|
+import animation.CodeLine;
|
|
|
|
+import animation.ControlFlow;
|
|
|
|
+import animation.Memory;
|
|
import animation.PseudoCodeNode;
|
|
import animation.PseudoCodeNode;
|
|
import animation.Memory.MemoryType;
|
|
import animation.Memory.MemoryType;
|
|
import animation.Memory.ReadOnlyMemory;
|
|
import animation.Memory.ReadOnlyMemory;
|
|
import codelines.AbstractForLoop;
|
|
import codelines.AbstractForLoop;
|
|
import codelines.DeclareVariable;
|
|
import codelines.DeclareVariable;
|
|
|
|
+import codelines.ForEachLoop;
|
|
import codelines.FunctionDefinition;
|
|
import codelines.FunctionDefinition;
|
|
|
|
+import codelines.IfLoop;
|
|
|
|
+import codelines.SetVariable;
|
|
|
|
+import graph.LayeredGraphEdge;
|
|
import graph.LayeredGraphNode;
|
|
import graph.LayeredGraphNode;
|
|
import lib.TextLayoutHelper;
|
|
import lib.TextLayoutHelper;
|
|
|
|
|
|
@@ -23,7 +31,7 @@ public class BlockCalc implements AlgorithmStage {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public PseudoCodeNode createPseudocodeTree( JTree tree ) {
|
|
public PseudoCodeNode createPseudocodeTree( JTree tree ) {
|
|
- String[] vars = { "graph", "L", "v", "r", "neighbors", "layout" };
|
|
|
|
|
|
+ String[] vars = { "graph", "L", "r", "neighbors", "layout", "m", "i", "k", "mids" };
|
|
PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "function calculateBlockGraph( graph, layout )", vars ), tree, new FunctionDefinition( new String[]{ "graph", "layout" } ) );
|
|
PseudoCodeNode root = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "function calculateBlockGraph( graph, layout )", vars ), tree, new FunctionDefinition( new String[]{ "graph", "layout" } ) );
|
|
root.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "L = graph.getContainedLayers();", vars), tree, new DeclareVariable<ArrayList<ArrayList<LayeredGraphNode>>>( "L" ) {
|
|
root.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "L = graph.getContainedLayers();", vars), tree, new DeclareVariable<ArrayList<ArrayList<LayeredGraphNode>>>( "L" ) {
|
|
@Override
|
|
@Override
|
|
@@ -80,7 +88,141 @@ public class BlockCalc implements AlgorithmStage {
|
|
return m.<Integer>read( "k", MemoryType.LOCAL ) >= 0;
|
|
return m.<Integer>read( "k", MemoryType.LOCAL ) >= 0;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
+ nodeLoop.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "neighbors = layout.contains('DOWN') ? L[i][k].predecessors : L[i][k].successors", vars), tree, new DeclareVariable<ArrayList<LayeredGraphNode>>( "neighbors" ) {
|
|
|
|
+ @Override
|
|
|
|
+ protected ArrayList<LayeredGraphNode> value(ReadOnlyMemory m) {
|
|
|
|
+ ArrayList<LayeredGraphEdge> list = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ).getSortedOutgoingEdges();
|
|
|
|
+ if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
|
|
|
|
+ list = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ).getSortedIncomingEdges();
|
|
|
|
+ ArrayList<LayeredGraphNode> result = new ArrayList<LayeredGraphNode>();
|
|
|
|
+ for( LayeredGraphEdge e : list )
|
|
|
|
+ {
|
|
|
|
+ if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
|
|
|
|
+ result.add( e.getSources().get( 0 ) );
|
|
|
|
+ else
|
|
|
|
+ result.add( e.getTargets().get( 0 ) );
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ } ) );
|
|
layerLoop.add( nodeLoop );
|
|
layerLoop.add( nodeLoop );
|
|
|
|
+ nodeLoop.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "neighbors = layout.contains('RIGHT') ? neighbors : reverse( neighbors )", vars), tree, new SetVariable<ArrayList<LayeredGraphNode>>( "neighbors" ) {
|
|
|
|
+ @Override
|
|
|
|
+ protected ArrayList<LayeredGraphNode> value(ReadOnlyMemory m) {
|
|
|
|
+ ArrayList<LayeredGraphNode> list = m.read( "neighbors", MemoryType.LOCAL );
|
|
|
|
+ if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "RIGHT" ) )
|
|
|
|
+ return list;
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ArrayList<LayeredGraphNode> result = new ArrayList<LayeredGraphNode>();
|
|
|
|
+ for( int i = list.size() - 1; i >= 0; i-- )
|
|
|
|
+ result.add( list.get( i ) );
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } ) );
|
|
|
|
+ PseudoCodeNode ifNeighbors = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if |neighbors| > 0 then", vars ), tree, new IfLoop() {
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean condition( ReadOnlyMemory m) {
|
|
|
|
+ return m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).size() > 0;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ nodeLoop.add( ifNeighbors );
|
|
|
|
+ ifNeighbors.add( new PseudoCodeNode(TextLayoutHelper.setupPseudoCode( "mids = [roundDown((|neighbors|-1)/2),roundUp((|neighbors|-1)/2)]", vars), tree, new DeclareVariable<ArrayList<Integer>>( "mids" ) {
|
|
|
|
+ @Override
|
|
|
|
+ protected ArrayList<Integer> value(ReadOnlyMemory m) {
|
|
|
|
+ int size = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).size() - 1;
|
|
|
|
+ int m1 = size / 2, m2 = (int)(size / 2.0 + 0.5);
|
|
|
|
+ ArrayList<Integer> list = new ArrayList<Integer>();
|
|
|
|
+ list.add( m1 );
|
|
|
|
+ if( m1 != m2 )
|
|
|
|
+ list.add( m2 );
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
+ } ) );
|
|
|
|
+ PseudoCodeNode midLoop = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "foreach m in mids do", vars ), tree, new ForEachLoop<Integer>( "m" ) {
|
|
|
|
+ @Override
|
|
|
|
+ protected List<Integer> list(ReadOnlyMemory m) {
|
|
|
|
+ return m.read( "neighbors", MemoryType.LOCAL );
|
|
|
|
+ }
|
|
|
|
+ } );
|
|
|
|
+ ifNeighbors.add( midLoop );
|
|
|
|
+ PseudoCodeNode ifAlign = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if align( L[i][k] ) == L[i][k] then", vars ), tree, new IfLoop() {
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean condition(ReadOnlyMemory m) {
|
|
|
|
+ LayeredGraphNode n = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
|
|
|
|
+ return n.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ) == n;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ midLoop.add( ifAlign );
|
|
|
|
+ PseudoCodeNode ifMarked = new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "if (neighbors[m],L[i][k]) not conflicted and ((r < pos(neighbors[m]) and layout.contains('RIGHT')) or (r > pos(neighbors[m]) and layout.contains('LEFT'))) ", vars ), tree, new IfLoop() {
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean condition(ReadOnlyMemory m) {
|
|
|
|
+ LayeredGraphEdge e = m.<LayeredGraphNode>read( "graph", MemoryType.LOCAL ).findEdgeBetween(
|
|
|
|
+ m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) ),
|
|
|
|
+ m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) ) );
|
|
|
|
+ ArrayList<LayeredGraphNode> layerBefore;
|
|
|
|
+ if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
|
|
|
|
+ layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) - 1 );
|
|
|
|
+ else
|
|
|
|
+ layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 );
|
|
|
|
+ int posU = layerBefore.indexOf( m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) ) );
|
|
|
|
+ return e.isConflicted( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ) &&
|
|
|
|
+ ( ( m.<Integer>read( "r", MemoryType.LOCAL ) < posU && m.<String>read( "layout", MemoryType.LOCAL ).contains( "RIGHT" ) ) ||
|
|
|
|
+ ( m.<Integer>read( "r", MemoryType.LOCAL ) > posU && m.<String>read( "layout", MemoryType.LOCAL ).contains( "LEFT" ) ) );
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ ifAlign.add( ifMarked );
|
|
|
|
+ ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "align( neighbors[m] ) = L[i][k];", vars ), tree, new CodeLine() {
|
|
|
|
+ @Override
|
|
|
|
+ public ControlFlow runForward(Memory m) {
|
|
|
|
+ LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
|
|
|
|
+ LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
|
|
|
|
+ LayeredGraphNode old = u.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ u.setAlign( v, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ actions.push( (Memory mem) -> {
|
|
|
|
+ u.setAlign( old, LayoutType.fromString( mem.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ });
|
|
|
|
+ return new ControlFlow( ControlFlow.STEP_OVER );
|
|
|
|
+ }
|
|
|
|
+ }) );
|
|
|
|
+ ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "root( L[i][k] ) = root( neighbors[m] );", vars ), tree, new CodeLine() {
|
|
|
|
+ @Override
|
|
|
|
+ public ControlFlow runForward(Memory m) {
|
|
|
|
+ LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
|
|
|
|
+ LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
|
|
|
|
+ LayeredGraphNode old = v.getRoot( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ v.setRoot( u.getRoot( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ), LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ actions.push( (Memory mem) -> {
|
|
|
|
+ v.setRoot( old, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ });
|
|
|
|
+ return new ControlFlow( ControlFlow.STEP_OVER );
|
|
|
|
+ }
|
|
|
|
+ }) );
|
|
|
|
+ ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "align( L[i][k] ) = root( L[i][k] );", vars ), tree, new CodeLine() {
|
|
|
|
+ @Override
|
|
|
|
+ public ControlFlow runForward(Memory m) {
|
|
|
|
+ LayeredGraphNode v = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.read( "i", MemoryType.LOCAL ) ).get( m.read( "k", MemoryType.LOCAL ) );
|
|
|
|
+ LayeredGraphNode old = v.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ v.setAlign( v.getAlign( LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) ), LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ actions.push( (Memory mem) -> {
|
|
|
|
+ v.setAlign( old, LayoutType.fromString( m.read( "layout", MemoryType.LOCAL ) ) );
|
|
|
|
+ });
|
|
|
|
+ return new ControlFlow( ControlFlow.STEP_OVER );
|
|
|
|
+ }
|
|
|
|
+ }) );
|
|
|
|
+ ifMarked.add( new PseudoCodeNode( TextLayoutHelper.setupPseudoCode( "r = pos( neighbors[m] );", vars ), tree, new SetVariable<Integer>( "r" ) {
|
|
|
|
+ @Override
|
|
|
|
+ protected Integer value(ReadOnlyMemory m) {
|
|
|
|
+ ArrayList<LayeredGraphNode> layerBefore;
|
|
|
|
+ if( m.<String>read( "layout", MemoryType.LOCAL ).contains( "DOWN" ) )
|
|
|
|
+ layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) - 1 );
|
|
|
|
+ else
|
|
|
|
+ layerBefore = m.<ArrayList<ArrayList<LayeredGraphNode>>>read( "L", MemoryType.LOCAL ).get( m.<Integer>read( "i", MemoryType.LOCAL ) + 1 );
|
|
|
|
+ LayeredGraphNode u = m.<ArrayList<LayeredGraphNode>>read( "neighbors", MemoryType.LOCAL ).get( m.read( "m", MemoryType.LOCAL ) );
|
|
|
|
+ return layerBefore.indexOf( u );
|
|
|
|
+ }
|
|
|
|
+ }) );
|
|
return root;
|
|
return root;
|
|
}
|
|
}
|
|
}
|
|
}
|