├── bash ├── build.sh └── make-plots.sh ├── tests ├── test1.txt ├── test8.txt ├── test2.txt ├── test4.txt ├── test3.txt ├── test5b.txt ├── test5.txt ├── test6.txt └── test7.txt ├── src └── edu │ └── lsu │ └── cct │ └── distgc │ ├── CidMessage.java │ ├── HasAdversary.java │ ├── Adversary.java │ ├── NoSuchMessage.java │ ├── CollectorState.java │ ├── MessageQueue.java │ ├── PlagueMessage.java │ ├── LocalState.java │ ├── RetMessage.java │ ├── RecoverMessage.java │ ├── ClaimMessage.java │ ├── PhantomizeMessage.java │ ├── BuildMessage.java │ ├── DecrMessage.java │ ├── IncrMessage.java │ ├── Root.java │ ├── Here.java │ ├── CID.java │ ├── Props.java │ ├── CollectionData.java │ ├── MessagesOvertake.java │ ├── Main.java │ ├── SimulationExecutor.java │ ├── Message.java │ └── Node.java ├── plots ├── grid-CONGEST-shuffle-a0-msgs.xg ├── grid-CONGEST-shuffle-a0-msgs-l.xg ├── grid-CONGEST-shuffle-a0-rnds.xg ├── grid-CONGEST-shuffle-a0-msgs-u.xg ├── grid-CONGEST-shuffle-a0-rnds-u.xg ├── grid-CONGEST-shuffle-a0-rnds-l.xg ├── dlink-CONGEST-shuffle-a0-msgs-l.xg ├── dlink-CONGEST-shuffle-a0-rnds-u.xg ├── dlink-CONGEST-shuffle-a0-rnds.xg ├── dlink-CONGEST-shuffle-a0-msgs.xg ├── dlink-CONGEST-shuffle-a0-rnds-l.xg ├── dlink-CONGEST-shuffle-a0-msgs-u.xg ├── clique-CONGEST-shuffle-a0-msgs.xg ├── clique-CONGEST-shuffle-a0-msgs-l.xg ├── clique-CONGEST-shuffle-a0-msgs-u.xg ├── clique-CONGEST-shuffle-a0-rnds.xg ├── clique-CONGEST-shuffle-a0-rnds-u.xg ├── clique-CONGEST-shuffle-a0-rnds-l.xg └── grid-CONGEST-shuffle-a0-rnds.ps ├── README.md └── python ├── file-tests.py ├── built-in-tests.py ├── fit.py ├── make-plots.py └── SWPR-1.py /bash/build.sh: -------------------------------------------------------------------------------- 1 | javac -d build/classes $(find src -name \*.java) 2 | exit $? 3 | -------------------------------------------------------------------------------- /tests/test1.txt: -------------------------------------------------------------------------------- 1 | create 1 2 | create 2 3 | edge 1->2 4 | edge 2->1 5 | deledge 0->2 6 | deledge 1->2 7 | runall 8 | runall 9 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/CidMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public interface CidMessage { 4 | 5 | CID getCid(); 6 | } 7 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/HasAdversary.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public interface HasAdversary { 4 | Adversary adversary(); 5 | } 6 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Adversary.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class Adversary { 6 | Message msg; 7 | } 8 | -------------------------------------------------------------------------------- /tests/test8.txt: -------------------------------------------------------------------------------- 1 | create 1->2->1 2 | create 3->1 3 | create 3->4->1 4 | create 4 5 | deledge 0->1 6 | deledge 3->1 7 | deledge 4->1 8 | runall 9 | runall 10 | -------------------------------------------------------------------------------- /tests/test2.txt: -------------------------------------------------------------------------------- 1 | create 1 2 | create 2 3 | create 3 4 | 5 | edge 1->2 6 | edge 2->1 7 | edge 2->3 8 | edge 1->3 9 | 10 | deledge 0->3 11 | deledge 0->2 12 | deledge 1->3 13 | runall 14 | runall 15 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/NoSuchMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class NoSuchMessage extends RuntimeException { 4 | public NoSuchMessage() { super(); } 5 | public NoSuchMessage(String msg) { super(msg); } 6 | } 7 | -------------------------------------------------------------------------------- /bash/make-plots.sh: -------------------------------------------------------------------------------- 1 | for test in dlink grid clique 2 | do 3 | python3 make-plots.py $test 4 | python3 fit.py -ps -lx plots/${test}-CONGEST-shuffle-a0-msgs 5 | python3 fit.py -ps -lx -ly plots/${test}-CONGEST-shuffle-a0-rnds 6 | done 7 | -------------------------------------------------------------------------------- /tests/test4.txt: -------------------------------------------------------------------------------- 1 | create 1 2 | create 2 3 | create 3 4 | create 4 5 | 6 | edge 1->2 7 | edge 2->3 8 | edge 3->4 9 | edge 4->1 10 | 11 | deledge 0->4 12 | deledge 0->3 13 | deledge 0->2 14 | Decr 0->2 15 | 16 | Phan 2->3 17 | Phan 3->4 18 | deledge 1->2 19 | runall 20 | runall 21 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/CollectorState.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | /** 4 | * The "Collector State" is defined by the last message sent to all outgoing 5 | * links. Healthy means no message has been sent. 6 | */ 7 | public enum CollectorState { 8 | healthy_state, phantom_state, recover_state, build_state, infected_state, dead_state; 9 | } 10 | -------------------------------------------------------------------------------- /tests/test3.txt: -------------------------------------------------------------------------------- 1 | create 1 2 | create 2 3 | create 3 4 | create 4 5 | 6 | edge 1->2 7 | edge 2->1 8 | edge 2->3 9 | edge 1->3 10 | edge 1->4 11 | edge 2->4 12 | 13 | deledge 0->4 14 | deledge 0->3 15 | deledge 0->2 16 | Decr 0->2 17 | Phan 2->4 18 | Phan 2->1 19 | Phan 2->3 20 | Ret 3->2 21 | Ret 4->2 22 | Ret 1->2 23 | 24 | deledge 1->3 25 | runall 26 | runall 27 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/MessageQueue.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.List; 4 | 5 | public interface MessageQueue extends Iterable { 6 | 7 | public void sendMessage(Message m); 8 | 9 | public Message nextToRun(); 10 | 11 | public List nextRoundToRun(); 12 | 13 | public Message getMessage(int nodeId, int msgId); 14 | 15 | public int size(); 16 | } 17 | -------------------------------------------------------------------------------- /tests/test5b.txt: -------------------------------------------------------------------------------- 1 | 2 | create 1 3 | create 2 4 | create 3 5 | 6 | edge 1->2 7 | edge 2->3 8 | 9 | deledge 0->3 10 | deledge 0->2 11 | runall 12 | 13 | edge 0->2 14 | edge 0->3 15 | create 4 16 | create 5 17 | edge 3->4 18 | edge 4->5 19 | edge 5->4 20 | deledge 0->3 21 | deledge 0->5 22 | deledge 0->4 23 | Phan 5->4 24 | Decr 0->4 25 | Phan 4->5 26 | Ret 4->5 27 | Claim 5->4 28 | Ret 4->5 29 | Ret 5->4 30 | Build 4->5 31 | edge 0->3 32 | deledge 0->2 33 | edge 0->4 34 | deledge 0->3 35 | deledge 4->5 36 | runall 37 | runall 38 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/PlagueMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class PlagueMessage extends Message { 4 | 5 | CID cid; 6 | 7 | public PlagueMessage(int id, int edge, CID cid) { 8 | super(id, edge); 9 | this.cid = cid; 10 | action = false; 11 | } 12 | 13 | @Override 14 | public void runTask(Node n) { 15 | n.plague(sender, cid, true); 16 | } 17 | 18 | @Override 19 | public String shortName() { 20 | return "Plague"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /tests/test5.txt: -------------------------------------------------------------------------------- 1 | 2 | create 1 3 | create 2 4 | create 3 5 | 6 | edge 1->2 7 | edge 2->3 8 | 9 | deledge 0->3 10 | deledge 0->2 11 | runall 12 | 13 | edge 0->2 14 | edge 0->3 15 | create 4 16 | create 5 17 | edge 3->4 18 | edge 4->5 19 | edge 5->4 20 | deledge 0->3 21 | deledge 0->5 22 | deledge 0->4 23 | Decr 0->4 24 | Phan 5->4 25 | Phan 4->5 26 | Ret 5->4 27 | Claim 4->5 28 | Ret 5->4 29 | Ret 4->5 30 | Recov 5->4 31 | #edge 0->2 32 | edge 0->3 33 | deledge 0->2 34 | edge 0->4 35 | deledge 0->3 36 | deledge 4->5 37 | runall 38 | runall 39 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/LocalState.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | /** 4 | * This class keeps track of state 5 | * that is only needed while a message 6 | * is being processed. 7 | * @author sbrandt 8 | */ 9 | public class LocalState { 10 | 11 | boolean same = false; 12 | boolean parent_was_set = false; 13 | int sent_to_parent = -1; 14 | int original_parent = -1; 15 | int old_weight; 16 | boolean returned_to_sender = false; 17 | boolean returned_to_parent = false; 18 | boolean in_collection_message = false; 19 | } 20 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/RetMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class RetMessage extends Message { 4 | 5 | CID start_recovery_over; 6 | 7 | public RetMessage(int s, int r, CID start_recovery_over) { 8 | super(s, r); 9 | action = false; 10 | this.start_recovery_over = start_recovery_over; 11 | } 12 | 13 | @Override 14 | public void runTask(Node n) { 15 | n.ret(start_recovery_over); 16 | } 17 | 18 | @Override 19 | public String shortName() { 20 | return "Ret"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/RecoverMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class RecoverMessage extends Message implements CidMessage { 4 | 5 | CID cid; 6 | boolean incrRCC; 7 | 8 | public CID getCid() { 9 | return cid; 10 | } 11 | 12 | public RecoverMessage(int s, int r, CID cid, boolean incrRCC) { 13 | super(s, r); 14 | this.cid = cid; 15 | this.incrRCC = incrRCC; 16 | } 17 | 18 | @Override 19 | public void runTask(Node n) { 20 | n.recover(cid, sender, incrRCC); 21 | } 22 | 23 | @Override 24 | public String shortName() { 25 | return "Recov"; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/ClaimMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class ClaimMessage extends Message implements CidMessage { 4 | 5 | CID cid; 6 | 7 | public CID getCid() { 8 | return cid; 9 | } 10 | 11 | public ClaimMessage(int id, int edge, CID cid) { 12 | super(id, edge); 13 | this.cid = cid; 14 | } 15 | 16 | @Override 17 | public void runTask(Node n) { 18 | n.claim(sender, cid); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return String.format("Claim"); 24 | } 25 | 26 | @Override 27 | public String shortName() { 28 | return "Claim"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/PhantomizeMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class PhantomizeMessage extends Message implements CidMessage { 4 | 5 | int weight; 6 | CID cid; 7 | 8 | public CID getCid() { 9 | return cid; 10 | } 11 | 12 | public PhantomizeMessage(int id, int edge, int weight, CID cid) { 13 | super(id, edge); 14 | this.weight = weight; 15 | this.cid = cid; 16 | } 17 | 18 | @Override 19 | public void runTask(Node n) { 20 | n.phantomize(sender, weight, cid); 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return String.format("Phan:w=%d", weight); 26 | } 27 | 28 | @Override 29 | public String shortName() { 30 | return "Phan"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-msgs.xg: -------------------------------------------------------------------------------- 1 | 24 8.729166666666668 2 | 32 9.421875 3 | 36 9.659722222222221 4 | 48 9.784375 5 | 56 9.983035714285714 6 | 68 9.877205882352941 7 | 84 10.518452380952382 8 | 104 10.020673076923075 9 | 128 10.40234375 10 | 156 10.54326923076923 11 | 192 11.149479166666666 12 | 232 10.479310344827585 13 | 284 11.341021126760566 14 | 344 10.770494186046513 15 | 420 11.300476190476193 16 | 512 11.225 17 | 624 12.112339743589743 18 | 756 11.243849206349209 19 | 916 11.37843886462882 20 | 1112 12.454046762589929 21 | 1348 13.608123145400594 22 | 1628 12.148832923832924 23 | 1968 13.19006605691057 24 | 2380 13.297605042016803 25 | 2872 12.77132660167131 26 | 3468 13.675245098039216 27 | 4184 14.52767686424474 28 | 5044 13.963223632038062 29 | 6084 15.870200525969755 30 | 7328 15.460882914847161 31 | 8828 14.648510421386495 32 | 10628 14.314795822356041 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-msgs-l.xg: -------------------------------------------------------------------------------- 1 | 24 7.689794193061148 2 | 32 8.459014880680996 3 | 36 8.778467023480871 4 | 48 8.941969306506348 5 | 56 9.071350744892023 6 | 68 8.528056183776261 7 | 84 9.84714123156114 8 | 104 8.84604344956621 9 | 128 9.504196718150364 10 | 156 9.383733977127543 11 | 192 9.911219303330494 12 | 232 9.263458715596276 13 | 284 10.235903684877124 14 | 344 9.57124508188235 15 | 420 10.116262998371973 16 | 512 9.898483913411326 17 | 624 10.737055971470554 18 | 756 10.227355283462973 19 | 916 10.361816790589195 20 | 1112 11.427289295240692 21 | 1348 12.414117796703417 22 | 1628 10.700631052264981 23 | 1968 11.381180329459832 24 | 2380 11.517069575390714 25 | 2872 11.620159595003686 26 | 3468 11.930096712835768 27 | 4184 13.178614175563167 28 | 5044 12.238187307138213 29 | 6084 12.997216560995398 30 | 7328 13.921567576123232 31 | 8828 11.874256495380092 32 | 10628 12.0101838931952 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-rnds.xg: -------------------------------------------------------------------------------- 1 | 24 1.8145833333333332 2 | 32 1.61875 3 | 36 1.4736111111111114 4 | 48 1.2291666666666665 5 | 56 1.1410714285714287 6 | 68 0.9882352941176471 7 | 84 0.9785714285714289 8 | 104 0.7961538461538462 9 | 128 0.71953125 10 | 156 0.5983974358974358 11 | 192 0.5541666666666667 12 | 232 0.49784482758620696 13 | 284 0.4545774647887324 14 | 344 0.376453488372093 15 | 420 0.34166666666666656 16 | 512 0.3107421875 17 | 624 0.29639423076923077 18 | 756 0.24219576719576724 19 | 916 0.22849344978165936 20 | 1112 0.2063399280575539 21 | 1348 0.1873516320474777 22 | 1628 0.17042383292383292 23 | 1968 0.15353150406504062 24 | 2380 0.13531512605042015 25 | 2872 0.11683495821727016 26 | 3468 0.10856401384083045 27 | 4184 0.09550669216061186 28 | 5044 0.09292228390166536 29 | 6084 0.08824786324786325 30 | 7328 0.0696984170305677 31 | 8828 0.0672405980969642 32 | 10628 0.06411366202484006 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-msgs-u.xg: -------------------------------------------------------------------------------- 1 | 24 9.768539140272187 2 | 32 10.384735119319004 3 | 36 10.540977420963571 4 | 48 10.626780693493654 5 | 56 10.894720683679406 6 | 68 11.22635558092962 7 | 84 11.189763530343624 8 | 104 11.19530270427994 9 | 128 11.300490781849636 10 | 156 11.702804484410917 11 | 192 12.387739030002837 12 | 232 11.695161974058895 13 | 284 12.446138568644008 14 | 344 11.969743290210676 15 | 420 12.484689382580413 16 | 512 12.551516086588673 17 | 624 13.487623515708933 18 | 756 12.260343129235444 19 | 916 12.395060938668443 20 | 1112 13.480804229939165 21 | 1348 14.80212849409777 22 | 1628 13.597034795400866 23 | 1968 14.998951784361308 24 | 2380 15.078140508642893 25 | 2872 13.922493608338934 26 | 3468 15.420393483242664 27 | 4184 15.876739552926312 28 | 5044 15.68825995693791 29 | 6084 18.743184490944113 30 | 7328 17.000198253571092 31 | 8828 17.4227643473929 32 | 10628 16.619407751516885 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-rnds-u.xg: -------------------------------------------------------------------------------- 1 | 24 2.0756159382571884 2 | 32 1.7880777148018012 3 | 36 1.6410802440694754 4 | 48 1.3958333333333335 5 | 56 1.2710611259653792 6 | 68 1.1434920855319897 7 | 84 1.046813860228408 8 | 104 0.8803969081300349 9 | 128 0.7950300794093853 10 | 156 0.6618322593342344 11 | 192 0.6071894441359349 12 | 232 0.5443386453384573 13 | 284 0.4953207206020202 14 | 344 0.4133560668383477 15 | 420 0.36908899565207887 16 | 512 0.34534007551329454 17 | 624 0.3263475000040472 18 | 756 0.2590207272579823 19 | 916 0.2452826218600845 20 | 1112 0.21907189595115883 21 | 1348 0.19976382175043864 22 | 1628 0.1881399057674723 23 | 1968 0.1671397883194452 24 | 2380 0.14208814536921385 25 | 2872 0.12463741221596256 26 | 3468 0.1172258192424631 27 | 4184 0.10224453474135951 28 | 5044 0.10428165821227685 29 | 6084 0.09818265601516839 30 | 7328 0.0730568667043285 31 | 8828 0.07347524245629042 32 | 10628 0.0701118041849899 33 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-rnds-l.xg: -------------------------------------------------------------------------------- 1 | 24 1.5535507284094778 2 | 32 1.4494222851981986 3 | 36 1.3061419781527475 4 | 48 1.0624999999999996 5 | 56 1.0110817311774782 6 | 68 0.8329785027033044 7 | 84 0.9103289969144497 8 | 104 0.7119107841776575 9 | 128 0.6440324205906146 10 | 156 0.5349626124606371 11 | 192 0.5011438891973985 12 | 232 0.4513510098339566 13 | 284 0.4138342089754446 14 | 344 0.33955090990583836 15 | 420 0.31424433768125426 16 | 512 0.27614429948670544 17 | 624 0.2664409615344143 18 | 756 0.22537080713355218 19 | 916 0.21170427770323422 20 | 1112 0.193607960163949 21 | 1348 0.17493944234451678 22 | 1628 0.15270776008019354 23 | 1968 0.13992321981063605 24 | 2380 0.12854210673162644 25 | 2872 0.10903250421857777 26 | 3468 0.0999022084391978 27 | 4184 0.08876884957986421 28 | 5044 0.08156290959105388 29 | 6084 0.07831307048055812 30 | 7328 0.0663399673568069 31 | 8828 0.06100595373763798 32 | 10628 0.058115519864690234 33 | -------------------------------------------------------------------------------- /tests/test6.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Test: Create an edge to a phantomized node 4 | # First create a cycle 5 | create 1 6 | create 2 7 | 8 | edge 1->2 9 | edge 2->1 10 | 11 | # Next, create a linked list: 3->4. Cut the 12 | # root ref to 4 and runall. This will raise 13 | # the weight of node 4 to 2. 14 | create 3 15 | create 4 16 | edge 3->4 17 | deledge 0->4 18 | runall 19 | 20 | # Now create an edge to the cycle from 4 21 | # To do this, we need a root edge to 4. 22 | # Creating one won't change 4's weight. 23 | edge 0->4 24 | edge 4->1 25 | 26 | # Now we can cut edges 0->2 and 0->3 and 27 | # let the cycle collect. Manually run the 28 | # minimum number of messages to get the 29 | # cycle phantomized. 30 | deledge 0->2 31 | Decr 0->2 32 | deledge 0->1 33 | Decr 0->1 34 | Phan 1->2 35 | Phan 2->1 36 | 37 | # Now create an edge from 4->1. We need 38 | # a root edge for this. Create one. 39 | edge 0->1 40 | edge 1->4 41 | runall 42 | runall 43 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/BuildMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class BuildMessage extends Message implements CidMessage { 4 | 5 | CID cid; 6 | int w; 7 | boolean incrRCC, mandate, decrRCC; 8 | 9 | public CID getCid() { 10 | return cid; 11 | } 12 | 13 | public BuildMessage(int id, Integer edge, int w, CID cid, boolean incrRCC, boolean mandate, boolean decrRCC) { 14 | super(id, edge); 15 | this.cid = cid; 16 | this.w = w; 17 | this.incrRCC = incrRCC; 18 | this.mandate = mandate; 19 | this.decrRCC = decrRCC; 20 | } 21 | 22 | @Override 23 | public void runTask(Node n) { 24 | n.build(sender, w, cid, incrRCC, mandate, decrRCC); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return String.format("Build", w); 30 | } 31 | 32 | @Override 33 | public String shortName() { 34 | return "Build"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-msgs-l.xg: -------------------------------------------------------------------------------- 1 | 22 7.020819249713389 2 | 26 7.7276507831351875 3 | 30 7.885679121148792 4 | 36 8.330619603760969 5 | 42 8.093965125394183 6 | 50 8.156333712917577 7 | 60 8.156870345328064 8 | 72 8.345472835176112 9 | 86 7.959373553968498 10 | 102 8.49784412484088 11 | 122 8.27356942780536 12 | 146 8.774564797010107 13 | 174 9.144454891276165 14 | 208 8.798846180627361 15 | 250 9.390866618295416 16 | 300 9.285884312049385 17 | 360 8.557411861752417 18 | 432 8.572396977964836 19 | 518 9.160356959063964 20 | 622 9.42055120236279 21 | 746 9.2529251973254 22 | 894 9.813444817577848 23 | 1072 9.681620322859773 24 | 1286 8.77576789127777 25 | 1542 9.66291824721643 26 | 1850 10.246339908843481 27 | 2220 9.029138984011018 28 | 2664 8.68964532598898 29 | 3196 9.334490146085079 30 | 3834 9.990206661997613 31 | 4600 10.40969954372812 32 | 5520 10.227842180687746 33 | 6624 10.442524647828094 34 | 7948 9.987621339607362 35 | 9538 9.262223824051434 36 | 11446 10.003027988054233 37 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-rnds-u.xg: -------------------------------------------------------------------------------- 1 | 22 4.914765243596658 2 | 26 4.32872907318707 3 | 30 4.945189696282023 4 | 36 4.301628798249921 5 | 42 4.719620323643481 6 | 50 5.184539819726301 7 | 60 4.898613816524069 8 | 72 5.15178376738994 9 | 86 4.677193113335853 10 | 102 4.605443110061346 11 | 122 4.386598827437214 12 | 146 4.7738528760291485 13 | 174 4.21804943506779 14 | 208 5.0539318878405 15 | 250 4.907624444595588 16 | 300 4.243408370140447 17 | 360 5.764823661954329 18 | 432 5.301646189093398 19 | 518 4.66016485758426 20 | 622 5.399208954216148 21 | 746 4.577545391069958 22 | 894 4.530431523115435 23 | 1072 4.321481009991436 24 | 1286 5.318085114314107 25 | 1542 6.2226703375207775 26 | 1850 4.369766438670366 27 | 2220 5.365467845904438 28 | 2664 5.821018709188003 29 | 3196 5.165526930447732 30 | 3834 4.572791462314918 31 | 4600 4.885858412058368 32 | 5520 5.996730673961979 33 | 6624 4.852184476119735 34 | 7948 5.42699747415252 35 | 9538 6.986566699287736 36 | 11446 4.083511343889761 37 | -------------------------------------------------------------------------------- /tests/test7.txt: -------------------------------------------------------------------------------- 1 | # Test: Create an edge to a phantomized node 2 | # First create a cycle 3 | create 1 4 | create 2 5 | 6 | edge 1->2 7 | edge 2->1 8 | 9 | # Next, create a linked list: 3->4. Cut the 10 | # root ref to 4 and runall. This will raise 11 | # the weight of node 4 to 2. 12 | create 3 13 | create 4 14 | edge 3->4 15 | deledge 0->4 16 | runall 17 | 18 | # Now create an edge to the cycle from 4 19 | # To do this, we need a root edge to 4. 20 | # Creating one won't change 4's weight. 21 | edge 0->4 22 | edge 4->1 23 | 24 | # Now we can cut edges 0->2 and 0->3 and 25 | # let the cycle collect. Manually run the 26 | # minimum number of messages to get the 27 | # cycle phantomized. 28 | deledge 0->2 29 | Decr 0->2 30 | deledge 0->1 31 | Decr 0->1 32 | Phan 1->2 33 | Phan 2->1 34 | Ret 2->1 35 | Claim 1->2 36 | Ret 2->1 37 | Ret 1->2 38 | Recov 2->1 39 | 40 | # Now create an edge from 4->1. We need 41 | # a root edge for this. Create one. 42 | #edge 0->1 43 | #edge 4->1 44 | runall 45 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-rnds.xg: -------------------------------------------------------------------------------- 1 | 22 3.793181818181819 2 | 26 3.3653846153846145 3 | 30 3.7516666666666674 4 | 36 3.694444444444444 5 | 42 3.736904761904762 6 | 50 3.932000000000001 7 | 60 3.714999999999999 8 | 72 3.7666666666666666 9 | 86 3.5889534883720935 10 | 102 3.6740196078431366 11 | 122 3.467213114754098 12 | 146 3.621917808219178 13 | 174 3.5905172413793096 14 | 208 3.900000000000001 15 | 250 3.9438000000000004 16 | 300 3.489666666666667 17 | 360 4.135833333333333 18 | 432 3.825 19 | 518 3.5449806949806955 20 | 622 4.115675241157556 21 | 746 3.5338471849865947 22 | 894 3.7967002237136462 23 | 1072 3.5706156716417916 24 | 1286 3.947472783825817 25 | 1542 4.426783398184176 26 | 1850 3.5905945945945943 27 | 2220 3.9660360360360363 28 | 2664 4.114414414414415 29 | 3196 3.8831351689612013 30 | 3834 3.60084767866458 31 | 4600 3.9457826086956524 32 | 5520 4.428423913043479 33 | 6624 3.7395531400966178 34 | 7948 4.1682687468545545 35 | 9538 4.654209477877961 36 | 11446 3.491922942512668 37 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-msgs.xg: -------------------------------------------------------------------------------- 1 | 22 8.727272727272728 2 | 26 8.896153846153847 3 | 30 9.531666666666668 4 | 36 9.384722222222225 5 | 42 9.769047619047619 6 | 50 10.059 7 | 60 9.793333333333333 8 | 72 10.465972222222224 9 | 86 9.886046511627908 10 | 102 10.074509803921567 11 | 122 9.717213114754099 12 | 146 10.841095890410958 13 | 174 10.194827586206896 14 | 208 10.783894230769231 15 | 250 10.998800000000001 16 | 300 10.362833333333333 17 | 360 11.558055555555553 18 | 432 11.329976851851853 19 | 518 11.048938223938224 20 | 622 11.760369774919614 21 | 746 11.128753351206434 22 | 894 11.362583892617447 23 | 1072 11.292630597014924 24 | 1286 11.69331259720062 25 | 1542 12.924448767833985 26 | 1850 11.748918918918921 27 | 2220 12.032342342342343 28 | 2664 12.137443693693694 29 | 3196 11.707587609511894 30 | 3834 11.581729264475744 31 | 4600 12.363543478260869 32 | 5520 13.282572463768114 33 | 6624 12.432412439613525 34 | 7948 12.635700805234022 35 | 9538 13.507270916334662 36 | 11446 11.133719203215097 37 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-rnds-l.xg: -------------------------------------------------------------------------------- 1 | 22 2.67159839276698 2 | 26 2.402040157582159 3 | 30 2.5581436370513115 4 | 36 3.087260090638967 5 | 42 2.754189200166043 6 | 50 2.6794601802737006 7 | 60 2.5313861834759295 8 | 72 2.381549565943393 9 | 86 2.5007138634083343 10 | 102 2.7425961056249273 11 | 122 2.5478274020709817 12 | 146 2.4699827404092076 13 | 174 2.9629850476908293 14 | 208 2.746068112159501 15 | 250 2.9799755554044127 16 | 300 2.7359249631928875 17 | 360 2.506843004712337 18 | 432 2.3483538109066027 19 | 518 2.429796532377131 20 | 622 2.8321415280989632 21 | 746 2.490148978903231 22 | 894 3.062968924311858 23 | 1072 2.8197503332921476 24 | 1286 2.576860453337528 25 | 1542 2.630896458847574 26 | 1850 2.811422750518823 27 | 2220 2.5666042261676347 28 | 2664 2.4078101196408266 29 | 3196 2.6007434074746705 30 | 3834 2.6289038950142416 31 | 4600 3.0057068053329377 32 | 5520 2.860117152124978 33 | 6624 2.6269218040735005 34 | 7948 2.909540019556589 35 | 9538 2.321852256468186 36 | 11446 2.9003345411355754 37 | -------------------------------------------------------------------------------- /plots/dlink-CONGEST-shuffle-a0-msgs-u.xg: -------------------------------------------------------------------------------- 1 | 22 10.433726204832068 2 | 26 10.064656909172507 3 | 30 11.177654212184544 4 | 36 10.43882484068348 5 | 42 11.444130112701055 6 | 50 11.961666287082421 7 | 60 11.429796321338602 8 | 72 12.586471609268335 9 | 86 11.81271946928732 10 | 102 11.651175483002254 11 | 122 11.160856801702838 12 | 146 12.90762698381181 13 | 174 11.245200281137627 14 | 208 12.768942280911102 15 | 250 12.606733381704586 16 | 300 11.43978235461728 17 | 360 14.558699249358689 18 | 432 14.087556725738871 19 | 518 12.937519488812484 20 | 622 14.100188347476438 21 | 746 13.004581505087469 22 | 894 12.911722967657047 23 | 1072 12.903640871170074 24 | 1286 14.61085730312347 25 | 1542 16.18597928845154 26 | 1850 13.251497928994361 27 | 2220 15.035545700673667 28 | 2664 15.585242061398407 29 | 3196 14.080685072938708 30 | 3834 13.173251866953875 31 | 4600 14.317387412793618 32 | 5520 16.337302746848483 33 | 6624 14.422300231398957 34 | 7948 15.283780270860682 35 | 9538 17.75231800861789 36 | 11446 12.264410418375961 37 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/DecrMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | public class DecrMessage extends Message implements HasAdversary { 4 | 5 | int weight; 6 | boolean phantom_flag; 7 | int sender; 8 | CID cid; 9 | Adversary adv; 10 | 11 | public Adversary adversary() { return adv; } 12 | 13 | public DecrMessage(int sender, int receiver, int weight, boolean phantom_flag, CID cid,Adversary adv) { 14 | super(sender, receiver); 15 | this.weight = weight; 16 | this.phantom_flag = phantom_flag; 17 | this.cid = cid; 18 | this.sender = sender; 19 | this.adv = adv; 20 | action = false; 21 | } 22 | 23 | @Override 24 | public void runTask(Node n) { 25 | n.decr(sender, weight, phantom_flag, cid); 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return String.format("Decr:w=%d", weight); 31 | } 32 | 33 | @Override 34 | public String shortName() { 35 | return "Decr"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-msgs.xg: -------------------------------------------------------------------------------- 1 | 12 7.258333333333335 2 | 12 7.258333333333335 3 | 12 7.258333333333335 4 | 19 7.652631578947367 5 | 20 7.034999999999999 6 | 26 7.78846153846154 7 | 30 7.125 8 | 37 8.47972972972973 9 | 42 7.2226190476190455 10 | 52 7.829807692307692 11 | 56 7.121428571428569 12 | 72 7.195833333333333 13 | 88 8.202840909090911 14 | 105 8.321904761904763 15 | 126 7.859523809523812 16 | 151 8.241059602649004 17 | 181 7.766574585635358 18 | 210 7.410952380952383 19 | 260 8.1225 20 | 306 7.2630718954248366 21 | 374 8.234491978609626 22 | 448 8.074330357142859 23 | 537 8.293482309124766 24 | 644 8.253105590062113 25 | 756 7.263558201058201 26 | 926 8.298218142548595 27 | 1111 8.094869486948694 28 | 1332 7.231081081081081 29 | 1560 7.220032051282052 30 | 1892 7.318287526427062 31 | 2256 7.09401595744681 32 | 2756 7.298349056603773 33 | 3306 7.388218390804596 34 | 3975 8.149635220125784 35 | 4770 8.356090146750523 36 | 5700 7.49571052631579 37 | 6806 7.3160152806347325 38 | 8190 7.219554334554334 39 | 9889 8.662175144099503 40 | 11772 7.275526673462453 41 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/IncrMessage.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | // TODO: If a recovered node creates a link, it needs to increment the target rcc. 4 | public class IncrMessage extends Message implements HasAdversary { 5 | 6 | int weight; 7 | boolean phantom_flag; 8 | CID cid; 9 | Adversary adv; 10 | 11 | public Adversary adversary() { return adv; } 12 | 13 | public IncrMessage(int sender, int receiver, int weight, boolean phantom_flag, CID cid,Adversary adv) { 14 | super(sender, receiver); 15 | this.weight = weight; 16 | this.phantom_flag = phantom_flag; 17 | this.cid = cid; 18 | this.adv = adv; 19 | action = false; 20 | } 21 | 22 | @Override 23 | public void runTask(Node n) { 24 | n.incr(sender, weight, phantom_flag, cid); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return String.format("Incr:w=%d", weight); 30 | } 31 | 32 | @Override 33 | public String shortName() { 34 | return "Incr"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-msgs-l.xg: -------------------------------------------------------------------------------- 1 | 12 6.3919471607751746 2 | 12 6.3919471607751746 3 | 12 6.3919471607751746 4 | 19 6.532753271351957 5 | 20 6.174752942463617 6 | 26 6.941303043967807 7 | 30 6.19304417128993 8 | 37 7.599508170862076 9 | 42 6.369510984506893 10 | 52 6.97544898007283 11 | 56 6.213105379823174 12 | 72 6.487841858093448 13 | 88 7.19180754243494 14 | 105 7.348817475885083 15 | 126 6.801616475949746 16 | 151 7.1983414791658795 17 | 181 6.660906469035068 18 | 210 6.719832648011164 19 | 260 6.924674507800356 20 | 306 6.645622416358364 21 | 374 7.1287135504824946 22 | 448 7.035379925868716 23 | 537 7.26436315169001 24 | 644 7.16489579793734 25 | 756 6.991826998194353 26 | 926 7.190182192900778 27 | 1111 7.001869971833735 28 | 1332 6.842582140384413 29 | 1560 6.848494514620028 30 | 1892 6.7185482639711855 31 | 2256 6.641292374456796 32 | 2756 6.955365106640341 33 | 3306 6.816136697739307 34 | 3975 7.167076816158565 35 | 4770 7.244034720579969 36 | 5700 7.001858712863252 37 | 6806 6.975395434942989 38 | 8190 6.79557593873673 39 | 9889 7.695336026239375 40 | 11772 6.878311043473888 41 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-msgs-u.xg: -------------------------------------------------------------------------------- 1 | 12 8.124719505891495 2 | 12 8.124719505891495 3 | 12 8.124719505891495 4 | 19 8.772509886542776 5 | 20 7.895247057536381 6 | 26 8.635620032955273 7 | 30 8.05695582871007 8 | 37 9.359951288597385 9 | 42 8.075727110731199 10 | 52 8.684166404542554 11 | 56 8.029751763033964 12 | 72 7.9038248085732175 13 | 88 9.213874275746882 14 | 105 9.294992047924444 15 | 126 8.917431143097877 16 | 151 9.28377772613213 17 | 181 8.87224270223565 18 | 210 8.102072113893602 19 | 260 9.320325492199645 20 | 306 7.880521374491309 21 | 374 9.340270406736757 22 | 448 9.113280788417002 23 | 537 9.322601466559522 24 | 644 9.341315382186885 25 | 756 7.535289403922049 26 | 926 9.406254092196413 27 | 1111 9.187869002063652 28 | 1332 7.619580021777749 29 | 1560 7.591569587944076 30 | 1892 7.918026788882938 31 | 2256 7.546739540436823 32 | 2756 7.641333006567206 33 | 3306 7.9603000838698845 34 | 3975 9.132193624093004 35 | 4770 9.468145572921078 36 | 5700 7.9895623397683275 37 | 6806 7.656635126326476 38 | 8190 7.6435327303719385 39 | 9889 9.629014261959632 40 | 11772 7.6727423034510185 41 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-rnds.xg: -------------------------------------------------------------------------------- 1 | 12 1.1541666666666666 2 | 12 1.1541666666666666 3 | 12 1.1541666666666666 4 | 19 0.9315789473684211 5 | 20 0.6525 6 | 26 0.7519230769230769 7 | 30 0.4400000000000001 8 | 37 0.5675675675675675 9 | 42 0.31190476190476185 10 | 52 0.3625 11 | 56 0.23214285714285715 12 | 72 0.1770833333333333 13 | 88 0.22272727272727275 14 | 105 0.1876190476190476 15 | 126 0.1472222222222222 16 | 151 0.1291390728476821 17 | 181 0.09558011049723755 18 | 210 0.06071428571428572 19 | 260 0.07346153846153845 20 | 306 0.04117647058823529 21 | 374 0.05147058823529412 22 | 448 0.041852678571428575 23 | 537 0.03556797020484171 24 | 644 0.029813664596273298 25 | 756 0.016203703703703706 26 | 926 0.02057235421166307 27 | 1111 0.01692169216921692 28 | 1332 0.009271771771771773 29 | 1560 0.007916666666666666 30 | 1892 0.006606765327695559 31 | 2256 0.005452127659574467 32 | 2756 0.004481132075471697 33 | 3306 0.003750756200846945 34 | 3975 0.00471698113207547 35 | 4770 0.004014675052410902 36 | 5700 0.00219298245614035 37 | 6806 0.001792535997649133 38 | 8190 0.0014896214896214903 39 | 9889 0.0020325614318940236 40 | 11772 0.0010448521916411827 41 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-rnds-u.xg: -------------------------------------------------------------------------------- 1 | 12 1.2892463756453956 2 | 12 1.2892463756453956 3 | 12 1.2892463756453956 4 | 19 1.156790451529839 5 | 20 0.7291077672302233 6 | 26 0.8561779705263841 7 | 30 0.49537749241945367 8 | 37 0.632093710196288 9 | 42 0.3479351094057661 10 | 52 0.41766080580485987 11 | 56 0.25980702390148147 12 | 72 0.19344335970748627 13 | 88 0.2530917936724713 14 | 105 0.21604726010780845 15 | 126 0.17015241303681533 16 | 151 0.14697074439448513 17 | 181 0.11705612345367611 18 | 210 0.0663234376139951 19 | 260 0.08518442358009873 20 | 306 0.04509803921568633 21 | 374 0.05944168726511431 22 | 448 0.04831722788284576 23 | 537 0.04099396733122292 24 | 644 0.03422207129396844 25 | 756 0.01677647182789966 26 | 926 0.023802631967850093 27 | 1111 0.019492863520627495 28 | 1332 0.00962985705758891 29 | 1560 0.008222416410710597 30 | 1892 0.0070940562609562935 31 | 2256 0.005655256014847361 32 | 2756 0.00465419796832675 33 | 3306 0.004027984010584141 34 | 3975 0.005367552228477282 35 | 4770 0.0046196521606083054 36 | 5700 0.002354728850127953 37 | 6806 0.0018513076697032115 38 | 8190 0.0015384615384615248 39 | 9889 0.0022979958488908237 40 | 11772 0.0010837799498382178 41 | -------------------------------------------------------------------------------- /plots/clique-CONGEST-shuffle-a0-rnds-l.xg: -------------------------------------------------------------------------------- 1 | 12 1.0190869576879376 2 | 12 1.0190869576879376 3 | 12 1.0190869576879376 4 | 19 0.7063674432070032 5 | 20 0.5758922327697766 6 | 26 0.6476681833197697 7 | 30 0.38462250758054656 8 | 37 0.5030414249388471 9 | 42 0.2758744144037576 10 | 52 0.3073391941951401 11 | 56 0.20447869038423283 12 | 72 0.1607233069591803 13 | 88 0.19236275178207415 14 | 105 0.15919083513028676 15 | 126 0.12429203140762905 16 | 151 0.1113074013008791 17 | 181 0.074104097540799 18 | 210 0.055105133814576344 19 | 260 0.06173865334297817 20 | 306 0.037254901960784244 21 | 374 0.04349948920547393 22 | 448 0.03538812926001139 23 | 537 0.030141973078460494 24 | 644 0.025405257898578157 25 | 756 0.015630935579507753 26 | 926 0.017342076455476047 27 | 1111 0.014350520817806346 28 | 1332 0.008913686485954636 29 | 1560 0.007610916922622735 30 | 1892 0.006119474394434824 31 | 2256 0.005248999304301573 32 | 2756 0.004308066182616644 33 | 3306 0.0034735283911097484 34 | 3975 0.004066410035673658 35 | 4770 0.003409697944213498 36 | 5700 0.002031236062152747 37 | 6806 0.0017337643255950547 38 | 8190 0.0014407814407814557 39 | 9889 0.0017671270148972235 40 | 11772 0.0010059244334441476 41 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Root.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Root { 7 | 8 | static List roots = new ArrayList<>(); 9 | private Node root; 10 | int index = -1; 11 | Adversary adv; 12 | 13 | Root(Adversary adv) { 14 | this(adv,new Node()); 15 | } 16 | 17 | Root(Adversary adv,Node node) { 18 | roots.add(this); 19 | this.adv = adv; 20 | assert adv != null; 21 | 22 | root = node; 23 | 24 | Message m = new IncrMessage(0, root.id, 0, false, null, adv); 25 | m.queueMe(); 26 | } 27 | 28 | Root(Adversary adv,int forceId) { 29 | this(adv,new Node(forceId)); 30 | } 31 | 32 | public void set(Node node,Adversary adv) { 33 | assert this.adv == adv; 34 | assert adv != null; 35 | if (node != null) { 36 | Message m = new IncrMessage(0, node.id, 0, false, null, adv); 37 | m.queueMe(); 38 | } 39 | if (root != null) { 40 | Message m = new DecrMessage(0, root.id, 0, false, null, adv); 41 | m.queueMe(); 42 | } 43 | root = node; 44 | } 45 | 46 | public Node get() { 47 | return root; 48 | } 49 | 50 | public int getId() { 51 | return get().id; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Here.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | /** 4 | * This class provides basic logging for the framework. All messages are 5 | * tagged with file and line number. 6 | * @author sbrandt 7 | */ 8 | public class Here { 9 | 10 | public final static boolean VERBOSE = Props.get("verbose").equals("yes"); 11 | 12 | public static void log(Object o) { 13 | if (!VERBOSE) { 14 | return; 15 | } 16 | Throwable t = new Throwable(); 17 | StackTraceElement stack = t.getStackTrace()[1]; 18 | System.out.printf(" %s: %s%n", 19 | stack, o == null ? "null" : o.toString()); 20 | } 21 | 22 | public static void log() { 23 | if (!VERBOSE) { 24 | return; 25 | } 26 | Throwable t = new Throwable(); 27 | StackTraceElement stack = t.getStackTrace()[1]; 28 | System.out.printf(" %s: %s%n", 29 | stack, ""); 30 | } 31 | 32 | public static void bar(String msg) { 33 | StringBuilder sb = new StringBuilder(); 34 | sb.append('['); 35 | final int width = 60; 36 | int m = (width - msg.length())/2; 37 | for(int i=0;i 0; 33 | } 34 | 35 | public static boolean lessThan(CID c1, CID c2) { 36 | if (c1 == c2) { 37 | return false; 38 | } 39 | if (c1 == null) { 40 | return false; 41 | } 42 | return c1.lessThan(c2); 43 | } 44 | 45 | public boolean equals(Object o) { 46 | if (o == null) { 47 | return false; 48 | } 49 | CID c = (CID) o; 50 | return majorId == c.majorId && objId == c.objId && minorId == c.minorId; 51 | } 52 | 53 | public static boolean equals(CID c1, CID c2) { 54 | if (c1 == c2) { 55 | return true; 56 | } 57 | if (c1 == null || c2 == null) { 58 | return false; 59 | } 60 | return c1.equals(c2); 61 | } 62 | 63 | public String toString() { 64 | return String.format("[%d,%d,%d]", majorId, objId, minorId); 65 | } 66 | 67 | public boolean lessThanEq(CID cid) { 68 | return lessThan(cid) || equals(cid); 69 | } 70 | 71 | public boolean greaterThan(CID cid) { 72 | return cid.lessThan(this); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Distributed Garbage Collector Simulator 2 | 3 | Overview of codes and programs: 4 | * src - Contains a full implemenation of the SWPR algorithm described in ISMM 2018. 5 | * python 6 | * SWPR-1.py - This is an implementation of the "single collector" described in ISMM 2018. 7 | * built-in-tests.py - run the java code, executing all the tests in the test suite. 8 | * file-tests.py - run the java code, executing all the tests from the tests folder. 9 | * fit.py - Create the png files in the plots directory. See make-plots.sh for how to invoke it. 10 | * make-plots.py - Generate the test output for all tests of a given type. 11 | * bash 12 | * make-plots.sh - Invoke both make-plots.py and fit.py to generate png files in plots/ 13 | * build.sh - Build the Java code. 14 | * plots - The output of make-plots.sh. These are the figures in the ISMM 2018 paper. 15 | 16 | Running from the command line: 17 | * sh bash/build.sh 18 | * java -ea -DCheckCounts=no -Dverbose=yes -Dseed=NUM -Dfileloc=filename.txt -Dtest=file-input -cp build/classes edu.lsu.cct.distgc.Main 19 | * -ea - Assertions must be enabled 20 | * -DCheckCounts=no - This ensures that phantom counts, etc. never go negative. This will not happen for the built-in tests, but is allowed for the test files. 21 | * -DVerbose=yes - If one is only interested in the answer and not the intermediate steps, this setting is fine. 22 | 23 | Syntax for the test file: 24 | ``` 25 | create NODENUM # create a node, plus and edge from the root to the node 26 | edge NODENUM->NODENUM # create an edge between nodes 27 | deledge NODENUM->NODENUM # delete an edge between nodes. 28 | # deledge 0->1 deletes a root edge. 29 | runall # Process all messages until collections are done 30 | ``` 31 | After the file is executed, any pending messages will be printed. 32 | These messages can be added to the file one by one to allow fine 33 | grained control of the execution. Messages include "Incr 1->2", 34 | "Phan 2->1", etc. 35 | -------------------------------------------------------------------------------- /python/file-tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import os, re, sys, queue, threading 3 | 4 | max_seed = 100 5 | 6 | jobs = queue.Queue() 7 | 8 | files = [] 9 | 10 | class Job: 11 | def __init__(self,fn,sd): 12 | self.file_name = fn 13 | self.seed = sd 14 | def run(self,wid): 15 | if wid==0: 16 | sys.stdout.write('Test %s seed=%d\n' % (self.file_name,self.seed)) 17 | cmd = 'java -ea -DCheckCounts=no -Dverbose=yes -Dseed=%d -Dfileloc=%s -Dtest=file-input -cp build/classes edu.lsu.cct.distgc.Main > worker%d.out 2>&1' % (self.seed,self.file_name,wid) 18 | rc = os.system(cmd) 19 | if rc != 0: 20 | sys.stderr.write("Died '%s' seed=%d, worker=%d\n" % (self.file_name,self.seed,wid)) 21 | fw = open('worker%d.sh' % wid,"w") 22 | fw.write(cmd) 23 | fw.write("\ntail -20 worker%d.out\n" % wid) 24 | fw.close() 25 | os.kill(os.getpid(),9) 26 | 27 | for bfn in os.listdir("tests"): 28 | fn = "tests/" + bfn 29 | if re.match(r'test.*\.txt$',fn): 30 | c = open(fn).read() 31 | c = re.sub('(?m)^\s*seed\s+(\d+)','',c) 32 | c += 'runall\n' 33 | fw = open('%s' % fn,"w") 34 | fw.write(c) 35 | fw.close() 36 | files += [fn] 37 | 38 | for seed in range(max_seed): 39 | for file_name in files: 40 | jobs.put(Job(file_name,seed)) 41 | 42 | def rmfile(fn): 43 | if os.path.isfile(fn): 44 | os.unlink(fn) 45 | 46 | def worker(worker_id): 47 | rmfile("worker%d.out"%worker_id) 48 | rmfile("worker%d.sh"%worker_id) 49 | while True: 50 | try: 51 | job = jobs.get(block=False) 52 | except queue.Empty: 53 | break 54 | job.run(worker_id) 55 | jobs.task_done() 56 | 57 | threads = [] 58 | for wid in range(4): 59 | t = threading.Thread(target=worker,args=(wid,)) 60 | threads += [t] 61 | t.start() 62 | for th in threads: 63 | th.join() 64 | print("All tests passed") 65 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Props.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.*; 4 | import java.util.regex.*; 5 | 6 | class PropInfo { 7 | final String regex; 8 | final String defaultValue; 9 | PropInfo(String r,String d) { 10 | regex = r; 11 | defaultValue = d; 12 | } 13 | PropInfo(String r) { 14 | regex = r; 15 | defaultValue = null; 16 | } 17 | 18 | } 19 | public class Props { 20 | private static Map propDefs = new HashMap<>(); 21 | static { 22 | propDefs.put("CheckCounts",new PropInfo("(yes|no)","yes")); 23 | propDefs.put("CONGEST_mode",new PropInfo("(yes|no)","yes")); 24 | propDefs.put("shuffle",new PropInfo("(yes|no)","yes")); 25 | propDefs.put("verbose",new PropInfo("(yes|no)","no")); 26 | propDefs.put("test",new PropInfo("[\\w-]+","cycle")); 27 | propDefs.put("fileloc",new PropInfo(".*","test1.txt")); 28 | propDefs.put("seed",new PropInfo("\\d+")); 29 | propDefs.put("size",new PropInfo("\\d+","2")); 30 | propDefs.put("adv-priority",new PropInfo("\\d+","0")); 31 | 32 | for(String name : System.getProperties().stringPropertyNames()) { 33 | if(propDefs.containsKey(name)) { 34 | PropInfo pi = propDefs.get(name); 35 | Pattern p = Pattern.compile("^"+pi.regex+"$"); 36 | String value = System.getProperty(name,pi.defaultValue); 37 | Matcher m = p.matcher(value); 38 | if(m.matches()) { 39 | System.out.printf("Property: %s=%s%n",name,value); 40 | } else { 41 | System.err.printf("Property name %s: value '%s' does not match %s%n",name,value,pi.regex); 42 | System.exit(2); 43 | } 44 | } else { 45 | if(name.indexOf('.') >= 0) 46 | continue; 47 | System.err.println("Undefined property: "+name); 48 | System.exit(2); 49 | } 50 | } 51 | } 52 | static String get(String key) { 53 | PropInfo pi = propDefs.get(key); 54 | return System.getProperty(key,pi.defaultValue); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/CollectionData.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | /** 4 | * This class holds variables which are only needed while a node is undergoing a 5 | * collection. 6 | * 7 | * @author sbrandt 8 | */ 9 | public class CollectionData { 10 | 11 | int parent; 12 | private CID cid; 13 | int phantom_count, rcc, wait_count; 14 | //boolean mandate; 15 | CID start_over, recoverCid; 16 | CollectorState state = CollectorState.healthy_state; 17 | CollectorState recv = CollectorState.healthy_state; 18 | public boolean incrRCC; 19 | 20 | public void setCid(CID cid) { 21 | assert cid != null; 22 | if (this.cid == null) { 23 | this.cid = cid; 24 | this.rcc = 0; 25 | this.setIncrRCC(); 26 | } else if (this.cid.equals(cid)) { 27 | this.cid = cid; 28 | } else if (this.cid.lessThan(cid)) { 29 | this.cid = cid; 30 | this.rcc = 0; 31 | this.setIncrRCC(); 32 | } else { 33 | assert false : "" + this.cid + " <= " + cid; 34 | } 35 | } 36 | 37 | public CID getCid() { 38 | return cid; 39 | } 40 | 41 | public CollectionData(int id) { 42 | setCid(new CID(0, id, 0)); 43 | } 44 | 45 | public CollectionData(CID cid) { 46 | setCid(cid); 47 | } 48 | 49 | char b(boolean bn) { 50 | return bn ? 'T' : 'F'; 51 | } 52 | 53 | void setIncrRCC() { 54 | if (!incrRCC) { 55 | incrRCC = true; 56 | if (state == CollectorState.recover_state) { 57 | state = CollectorState.phantom_state; 58 | } 59 | } 60 | } 61 | 62 | public String toString() { 63 | char orig = parent == 0 ? '*' : ' '; 64 | String cids = cid == null ? "" : cid.toString(); 65 | return String.format(" p,r=%d,%d wait=%d %s/%s parent=%d sro=%s %s%c incrRCC=%c", 66 | phantom_count, rcc, wait_count, recv, state, parent, 67 | start_over, cids, orig, b(incrRCC)); 68 | } 69 | 70 | boolean phantom_flag() { 71 | return state == CollectorState.phantom_state 72 | || state == CollectorState.recover_state 73 | || state == CollectorState.infected_state; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /python/built-in-tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import os, re, sys, queue, threading 3 | 4 | # Make this line true if you're willing to 5 | # wait a while and watch the full test suite run. 6 | big_machine = False 7 | 8 | if big_machine: 9 | workers = 40 10 | seeds_per_test = 1000 11 | max_size = 50 12 | mega = True 13 | else: 14 | workers = 3 15 | seeds_per_test = 100 16 | max_size = 30 17 | mega = False 18 | 19 | jobs = queue.Queue() 20 | 21 | tests = ["rand","randm1","grid","gridm1","cyclem1","dlink","dlinkm1","clique","cliquem1"] 22 | 23 | class Job: 24 | def __init__(self,tn,sz,sd): 25 | self.test_name = tn 26 | self.size = sz 27 | self.seed = sd 28 | def run(self,wid): 29 | if wid==0: 30 | sys.stdout.write('Test %15s seed=%4d size=%2d\n' % (self.test_name,self.seed,self.size)) 31 | congest = "no" 32 | priority = 0 33 | if mega: 34 | if self.test_name in ["clique","cliquem1"]: 35 | congest = "yes" 36 | if self.test_name in ["grid","gridm1"]: 37 | priority = 5 38 | cmd = 'java -ea -Dadv-priority=%d -DCONGEST_mode=%s -DCheckCounts=yes -Dverbose=no -Dseed=%d -Dsize=%d -Dtest=%s -cp build/classes edu.lsu.cct.distgc.Main > worker%d.out 2>&1' % \ 39 | (priority,congest,self.seed,self.size,self.test_name,wid) 40 | rc = os.system(cmd) 41 | if rc != 0: 42 | sys.stderr.write("Died '%s' seed=%d, worker=%d\n" % (self.test_name,self.seed,wid)) 43 | fw = open('worker%d.sh' % wid,"w") 44 | fw.write(re.sub(r'verbose=no','verbose=yes',cmd)) 45 | fw.write("\ntail -20 worker%d.out\n" % wid) 46 | fw.close() 47 | os.kill(os.getpid(),9) 48 | 49 | 50 | # The really big one 51 | if mega: 52 | for size in [1000000]: 53 | for seed in range(3): 54 | for test in tests: 55 | jobs.put(Job(test,size,seed)) 56 | 57 | for size in range(max_size,1,-1): 58 | for seed in range(seeds_per_test): 59 | for test in tests: 60 | jobs.put(Job(test,size,seed)) 61 | 62 | def rmfile(fn): 63 | if os.path.isfile(fn): 64 | os.unlink(fn) 65 | 66 | def worker(worker_id): 67 | rmfile("worker%d.out"%worker_id) 68 | rmfile("worker%d.sh"%worker_id) 69 | while True: 70 | try: 71 | job = jobs.get(block=False) 72 | except queue.Empty: 73 | break 74 | job.run(worker_id) 75 | jobs.task_done() 76 | 77 | threads = [] 78 | for wid in range(workers): 79 | t = threading.Thread(target=worker,args=(wid,)) 80 | threads += [t] 81 | t.start() 82 | for th in threads: 83 | th.join() 84 | print("All tests passed") 85 | -------------------------------------------------------------------------------- /python/fit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import numpy as np 3 | import sys 4 | import matplotlib.pyplot as plt 5 | from scipy.optimize import curve_fit 6 | import re 7 | import matplotlib 8 | 9 | font = {'family' : 'Bitstream Vera Sans', 10 | 'weight' : 'normal', 11 | 'size' : 18} 12 | 13 | matplotlib.rc('font', **font) 14 | 15 | g = None 16 | logx = None 17 | logy = None 18 | fname = None 19 | loc = 'upper right' 20 | printout = False 21 | for arg in sys.argv: 22 | if g == None: 23 | g = re.search(r'(\w+)-(\w+)-(\w+)-a0-(\w+)',arg) 24 | fname = arg 25 | if arg == "-lx": 26 | logx = True 27 | elif arg == '-ly': 28 | logy = True 29 | elif arg == '-low': 30 | loc = 'lower right' 31 | elif arg == '-ps': 32 | printout = True 33 | 34 | if g: 35 | print(g.groups()) 36 | title = 'Scaling for Test: '+g.groups()[0] 37 | title += ", " + g.groups()[1] 38 | title = re.sub(r'clique','highly-connected',title) 39 | if g.groups()[2] == "sorted": 40 | title += ", sorted" 41 | else: 42 | raise Exception(sys.argv[1]) 43 | 44 | val = np.genfromtxt(fname+".xg") 45 | valu = np.genfromtxt(fname+"-u.xg") 46 | vald = np.genfromtxt(fname+"-l.xg") 47 | skip = 15 48 | 49 | x = val[:,0] 50 | y = val[:,1] 51 | xu = valu[:,0] 52 | yu = valu[:,1] 53 | xd = vald[:,0] 54 | yd = vald[:,1] 55 | 56 | funs = { 57 | "a" : lambda x,a : a*np.ones(x.shape), 58 | "a*log(x)" : lambda x,a : a*np.log(x), 59 | "a*log(x)**2" : lambda x,a : a*np.log(x)**2, 60 | "a*log(x)**(1./2.)" : lambda x,a : a*np.log(x)**(1./2.), 61 | "a*log(x)**(1./3.)" : lambda x,a : a*np.log(x)**(1./3.), 62 | "a*log(x)**(3./2.)" : lambda x,a : a*np.log(x)**(3./2.), 63 | "a*log(x)**(2./3.)" : lambda x,a : a*np.log(x)**(2./3.), 64 | "a*log(x)**(3./4.)" : lambda x,a : a*np.log(x)**(3./4.), 65 | "a*x" : lambda x,a : a*x, 66 | "a/x" : lambda x,a : a/x, 67 | "a/x**(2./3.)" : lambda x,a : a/x**(2./3.), 68 | "a/x**(1./3.)" : lambda x,a : a/x**(1./3.), 69 | "a/x**(1./4.)" : lambda x,a : a/x**(1./4.), 70 | "a/x**(3./4.)" : lambda x,a : a/x**(3./4.), 71 | "a/x**(3./2.)" : lambda x,a : a/x**(3./2.), 72 | "a/x**(5./9.)" : lambda x,a : a/x**(5./9.), 73 | "a/x**(7./9.)" : lambda x,a : a/x**(7./9.), 74 | "a*sqrt(x)" : lambda x,a : a*np.sqrt(x), 75 | "a*x**(1./3)" : lambda x,a : a*np.exp(1./3.*np.log(x)), 76 | "a*x**(2./3)" : lambda x,a : a*np.exp(2./3.*np.log(x)), 77 | "a/sqrt(x)" : lambda x,a : a/np.sqrt(x), 78 | "a*x**1.5" : lambda x,a : a*np.sqrt(x)*x 79 | } 80 | 81 | bestfn = None 82 | bestv = 1e1000 83 | bestfit = None 84 | 85 | for f in funs: 86 | ff = funs[f] 87 | popt, pcurv = curve_fit(ff,x[skip:],y[skip:]) 88 | v = np.sum(np.abs(y - ff(x,*popt))) 89 | if v < bestv: 90 | bestv = v 91 | bestfn = f 92 | bestfit = popt 93 | 94 | print("-> best:",bestfn,"a="+str(bestfit[0])) 95 | bestf = funs[bestfn] 96 | 97 | fig, ax = plt.subplots() 98 | fig.suptitle(title) 99 | ax.set_xlabel('Number of Edges') 100 | 101 | if logy: 102 | ax.semilogy(x,y,'g--') 103 | 104 | if logx: 105 | ax.semilogx(x,y,'g--') 106 | 107 | if g.groups()[3] == "msgs": 108 | ax.set_ylabel('Number of Messages/Edge') 109 | else: 110 | ax.set_ylabel('Number of Rounds/Edge') 111 | #plt.plot(x,y,'rs-') 112 | #plt.plot(xu,yu,'r--') 113 | #plt.plot(xd,yd,'r-+') 114 | ax.errorbar(x,y,yerr=[y-yd,yu-y],fmt='g--')[0].set_label('Experimental Result') 115 | yf = bestf(x,*bestfit) 116 | plt.plot(x,yf,'b^-')[0].set_label('Fit: %s,a=%.2f' % (bestfn,bestfit[0])) 117 | ax.legend(loc=loc) 118 | if printout: 119 | plt.savefig(fname+'.eps',format='eps') 120 | else: 121 | plt.show() 122 | -------------------------------------------------------------------------------- /python/make-plots.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # Make the plots 3 | import os,sys,re 4 | from math import sqrt 5 | 6 | ttype = sys.argv[1] 7 | mode = "CONGEST" 8 | ordering = "shuffle" 9 | advpri = 0 10 | tests_per_data_point = 20 11 | max_edges = 10000 12 | 13 | assert mode == "CONGEST" or mode == "random" 14 | assert ordering == "shuffle" or ordering == "sorted" 15 | 16 | shuffle = "yes"; 17 | if ordering == "sorted": 18 | shuffle = "no" 19 | sync = "no" 20 | if mode == "CONGEST": 21 | sync = "yes" 22 | 23 | name="{type}-{mode}-{shuf}-a{advpri}".format(**{ 24 | "type":ttype, 25 | "mode":mode, 26 | "shuf":ordering, 27 | "advpri":advpri 28 | }) 29 | 30 | fn1 = "plots/{name}-msgs.xg".format(**{"name":name}) 31 | if os.path.exists(fn1): 32 | exit(0) 33 | fp1 = open("plots/{name}-msgs.xg".format(**{"name":name}),"w"); 34 | fp2 = open("plots/{name}-msgs-u.xg".format(**{"name":name}),"w"); 35 | fp3 = open("plots/{name}-msgs-l.xg".format(**{"name":name}),"w"); 36 | fp4 = open("plots/{name}-rnds.xg".format(**{"name":name}),"w"); 37 | fp5 = open("plots/{name}-rnds-u.xg".format(**{"name":name}),"w"); 38 | fp6 = open("plots/{name}-rnds-l.xg".format(**{"name":name}),"w"); 39 | 40 | class Matcher: 41 | def __init__(self): 42 | self.g = None 43 | def search(self,pattern,text): 44 | self.g = re.search(pattern,text) 45 | return self.g != None 46 | def group(self,n): 47 | return self.g.group(n) 48 | 49 | m = Matcher() 50 | 51 | size = 10 52 | while True: 53 | size = int(size*1.2) 54 | msg_sum = 0 55 | msg2_sum = 0 56 | rnd_sum = 0 57 | rnd2_sum = 0 58 | count = 0 59 | for seed in range(1,tests_per_data_point+1): 60 | cmd="java -ea -Dadv-priority={advpri} -DCONGEST_mode={sync} -Dshuffle={shuffle} -Dverbose=no -Dtest={type} -Dsize={size} -Dseed={seed} -cp build/classes edu.lsu.cct.distgc.Main > run1.out 2>&1".format(**{ 61 | "advpri":advpri, 62 | "sync":sync, 63 | "shuffle":shuffle, 64 | "type":ttype, 65 | "size":size, 66 | "seed":seed 67 | }); 68 | os.system(cmd) 69 | fd = open("run1.out","r") 70 | edges = 0 71 | rounds = 0 72 | msgs = 0 73 | for line in fd.readlines(): 74 | if m.search(r'edges: (\d+)',line): 75 | edges = int(m.group(1)) 76 | elif m.search(r'rounds to converge: (\d+)',line): 77 | rounds = int(m.group(1)) 78 | elif m.search(r'messages to converge: (\d+)',line): 79 | msgs = int(m.group(1)) 80 | rounds = (1.0*rounds)/edges 81 | msgs = (1.0*msgs)/edges 82 | 83 | msg_sum += msgs 84 | msg2_sum += msgs**2 85 | 86 | rnd_sum += rounds 87 | rnd2_sum += rounds**2 88 | 89 | count += 1 90 | 91 | msg_avg = msg_sum/count 92 | msg2_avg = msg2_sum/count 93 | msg_dev = sqrt(abs(msg2_avg - msg_avg**2)) 94 | 95 | rnd_avg = rnd_sum/count 96 | rnd2_avg = rnd2_sum/count 97 | rnd_dev = sqrt(abs(rnd2_avg - rnd_avg**2)) 98 | 99 | print("=" * 50) 100 | print("edges=%d\n" % edges) 101 | print("msgs=%5.2f +/- %5.2f" % (msg_avg,msg_dev)) 102 | print("rnds=%5.2f +/- %5.2f" % (rnd_avg,rnd_dev)) 103 | 104 | msg_u = msg_avg + msg_dev 105 | msg_l = msg_avg - msg_dev 106 | rnd_u = rnd_avg + rnd_dev 107 | rnd_l = rnd_avg - rnd_dev 108 | 109 | fp1.write("%d %s\n" % (edges,msg_avg)) 110 | fp2.write("%d %s\n" % (edges,msg_u)) 111 | fp3.write("%d %s\n" % (edges,msg_l)) 112 | 113 | fp4.write("%d %s\n" % (edges,rnd_avg)) 114 | fp5.write("%d %s\n" % (edges,rnd_u)) 115 | fp6.write("%d %s\n" % (edges,rnd_l)) 116 | 117 | if edges > max_edges: 118 | break 119 | 120 | fp1.close() 121 | fp2.close() 122 | fp3.close() 123 | fp4.close() 124 | fp5.close() 125 | fp6.close() 126 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/MessagesOvertake.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Iterator; 8 | 9 | public class MessagesOvertake implements MessageQueue { 10 | 11 | List msgs; 12 | Map> masterMailbox; 13 | 14 | public MessagesOvertake(boolean congest) { 15 | if(congest) 16 | masterMailbox = new HashMap<>(); 17 | else 18 | msgs = new ArrayList<>(); 19 | } 20 | 21 | @Override 22 | public Iterator iterator() { 23 | if(msgs == null) { 24 | List list = new ArrayList<>(); 25 | for(List mailbox : masterMailbox.values()) { 26 | list.addAll(mailbox); 27 | } 28 | return list.iterator(); 29 | } else { 30 | return msgs.iterator(); 31 | } 32 | } 33 | 34 | final static int ADV_PRIORITY = Integer.parseInt(Props.get("adv-priority")); 35 | 36 | static void addRandom(List msgs,Message m) { 37 | msgs.add(m); 38 | int n = msgs.size(); 39 | if(ADV_PRIORITY > 0 && m instanceof HasAdversary) { 40 | if(n > ADV_PRIORITY) n = ADV_PRIORITY; 41 | } 42 | int n1 = msgs.size() - Message.RAND.nextInt(n) - 1; 43 | int n2 = msgs.size() - 1; 44 | Message m1 = msgs.get(n1); 45 | Message m2 = msgs.get(n2); 46 | msgs.set(n1,m2); 47 | msgs.set(n2,m1); 48 | } 49 | 50 | @Override 51 | public void sendMessage(Message m) { 52 | if(msgs != null) { 53 | addRandom(msgs,m); 54 | } else { 55 | List mailbox = masterMailbox.get(m.recipient); 56 | if (mailbox == null) { 57 | mailbox = new ArrayList<>(); 58 | masterMailbox.put(m.recipient, mailbox); 59 | } 60 | addRandom(mailbox,m); 61 | } 62 | } 63 | 64 | @Override 65 | public Message nextToRun() { 66 | if (msgs.isEmpty()) { 67 | return null; 68 | } 69 | return msgs.remove(msgs.size()-1); 70 | } 71 | 72 | @Override 73 | public List nextRoundToRun() { 74 | List mails = new ArrayList<>(); 75 | Here.log(); 76 | for (Integer nodeId : masterMailbox.keySet()) { 77 | List mailbox = masterMailbox.get(nodeId); 78 | assert mailbox != null : "Mailbox cannot be null"; 79 | int numMails = mailbox.size(); 80 | while (mailbox.size() > 0) { 81 | if (numMails > 0) { 82 | Message toBeAdded = mailbox.remove(numMails-1); 83 | assert !toBeAdded.isDone(); 84 | mails.add(toBeAdded); 85 | } 86 | numMails = mailbox.size(); 87 | } 88 | } 89 | Here.log(mails); 90 | return mails; 91 | } 92 | 93 | @Override 94 | public Message getMessage(int nodeId, int msgId) { 95 | List mailbox = masterMailbox.get(nodeId); 96 | assert mailbox != null : "Mailbox cannot be null"; 97 | Iterator miter = mailbox.iterator(); 98 | while(miter.hasNext()) { 99 | Message msg = miter.next(); 100 | if (msg.msg_id == msgId) { 101 | miter.remove(); 102 | return msg; 103 | } 104 | } 105 | return null; 106 | } 107 | 108 | 109 | @Override 110 | public int size() { 111 | if(msgs != null) { 112 | return msgs.size(); 113 | } else { 114 | int size = 0; 115 | for(List mailbox : masterMailbox.values()) { 116 | size += mailbox.size(); 117 | } 118 | return size; 119 | } 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Main.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Main { 7 | 8 | static Adversary adv = new Adversary(); 9 | 10 | /** 11 | * Create a random graph and then remove the support from root edges 12 | * 13 | * @param n a number proportional to the number of edges 14 | * @param m1 if one root edge should be retained 15 | */ 16 | public static void RandTest(int n, boolean m1) { 17 | List roots = new ArrayList<>(); 18 | for (int i = 0; i < n; i++) { 19 | roots.add(new Root(adv)); 20 | } 21 | shuffle(roots); 22 | for (int i = 0; i < 2*n; i++) { 23 | int from = Message.RAND.nextInt(n); 24 | int to = Message.RAND.nextInt(n); 25 | Root rfrom = roots.get(from); 26 | Root rto = roots.get(to); 27 | rfrom.get().createEdge(rto.getId(),adv); 28 | } 29 | for (int i = 0; i < n; i++) { 30 | if (m1 && i + 1 == n) { 31 | continue; 32 | } 33 | Root r = roots.get(i); 34 | r.get().delete_outgoing_edges(adv); 35 | r.set(null,adv); 36 | } 37 | Message.runAll(); 38 | } 39 | 40 | /** 41 | * Create a grid of nodes with four outgoing and incoming edges each. 42 | * 43 | * @param n2 a number proportional to the number of edges 44 | * @param m1 if one root edge should be retained 45 | */ 46 | public static void GridTest(int n2, boolean m1) { 47 | final int n = (int) Math.ceil(Math.sqrt(n2)); 48 | Here.log("n=" + n + " n2=" + n2); 49 | List grid = new ArrayList<>(); 50 | outer: 51 | for (int i = 0; i < n; i++) { 52 | for (int j = 0; j < n; j++) { 53 | if (i * n + j > n2) { 54 | break outer; 55 | } 56 | grid.add(new Root(adv)); 57 | } 58 | } 59 | shuffle(grid); 60 | outer: 61 | for (int i = 1; i < n; i++) { 62 | for (int j = 1; j < n; j++) { 63 | if (i * n + j > n2) { 64 | break outer; 65 | } 66 | Root r1 = grid.get(n * i + j); 67 | Root r2 = grid.get(n * (i - 1) + j); 68 | Root r3 = grid.get(n * (i - 1) + (j - 1)); 69 | Root r4 = grid.get(n * i + (j - 1)); 70 | r1.get().createEdge(r2.getId(),adv); 71 | r2.get().createEdge(r3.getId(),adv); 72 | r3.get().createEdge(r4.getId(),adv); 73 | r4.get().createEdge(r1.getId(),adv); 74 | } 75 | } 76 | outer: 77 | for (int i = 0; i < n; i++) { 78 | for (int j = 0; j < n; j++) { 79 | if (i * n + j > n2) { 80 | break outer; 81 | } 82 | if (m1 && i + 1 == n && j + 1 == n) { 83 | continue; 84 | } 85 | grid.get(n * i + j).set(null,adv); 86 | } 87 | } 88 | Message.runAll(); 89 | } 90 | 91 | /** 92 | * Create a densely connected set of nodes (in some cases forming a clique) 93 | * and then remove the support from root edges 94 | * 95 | * @param n2 a number proportional to the number of edges 96 | * @param m1 if one root edge should be retained 97 | */ 98 | public static void CliqueTest(int n2, boolean m1) { 99 | final int n = (int) Math.ceil(Math.sqrt(n2)); 100 | List roots = new ArrayList<>(); 101 | for (int i = 0; i < n; i++) { 102 | roots.add(new Root(adv)); 103 | } 104 | shuffle(roots); 105 | int count = 0; 106 | outer: 107 | for (int off = 1; off < n; off++) { 108 | for (int i = 0; i < n; i++) { 109 | Root ri = roots.get(i); 110 | Root rj = roots.get((i + off) % n); 111 | ri.get().createEdge(rj.getId(),adv); 112 | count++; 113 | if (count == n2) { 114 | break outer; 115 | } 116 | } 117 | } 118 | for (int i = 0; i < n; i++) { 119 | if (m1 && i + 1 == n) { 120 | continue; 121 | } 122 | roots.get(i).set(null,adv); 123 | } 124 | Message.runAll(); 125 | } 126 | 127 | /** 128 | * Create a cycle of nodes with one way connections and then remove the 129 | * support from root edges 130 | * 131 | * @param n a number proportional to the number of edges 132 | * @param m1 if one root edge should be retained 133 | */ 134 | public static void CycleTest(int n, boolean m1) { 135 | List roots = new ArrayList<>(); 136 | for (int i = 0; i < n; i++) { 137 | roots.add(new Root(adv)); 138 | } 139 | shuffle(roots); 140 | for (int i = 0; i < n; i++) { 141 | int next = (i + 1) % n; 142 | Root r1 = roots.get(i); 143 | Root r2 = roots.get(next); 144 | r1.get().createEdge(r2.getId(),adv); 145 | } 146 | for (int i = 0; i < n; i++) { 147 | if (m1 && i + 1 == n) { 148 | break; 149 | } 150 | roots.get(i).set(null,adv); 151 | } 152 | Message.runAll(); 153 | } 154 | 155 | /** 156 | * Create a cycle of nodes with one way connections and then remove the 157 | * support from root edges 158 | * 159 | * @param n a number proportional to the number of edges 160 | * @param m1 if one root edge should be retained 161 | */ 162 | public static void DoubleCycleTest(int n, boolean m1) { 163 | List roots = new ArrayList<>(); 164 | for (int i = 0; i < n; i++) { 165 | roots.add(new Root(adv)); 166 | } 167 | shuffle(roots); 168 | for (int i = 0; i < n; i++) { 169 | int next = (i + 1) % n; 170 | Root r1 = roots.get(i); 171 | Root r2 = roots.get(next); 172 | r1.get().createEdge(r2.getId(),adv); 173 | int prev = (i + n - 1) % n; 174 | Root r3 = roots.get(prev); 175 | r1.get().createEdge(r3.getId(),adv); 176 | } 177 | for (int i = 0; i < n; i++) { 178 | if (m1 && i + 1 == n) { 179 | break; 180 | } 181 | roots.get(i).set(null,adv); 182 | } 183 | Message.runAll(); 184 | } 185 | 186 | static void shuffle(List roots) { 187 | if (Props.get("shuffle").equals("yes")) { 188 | for (int i = roots.size() - 1; i > 0; i--) { 189 | int n = Message.RAND.nextInt(i + 1); 190 | Root r1 = roots.get(i); 191 | Root r2 = roots.get(n); 192 | roots.set(i, r2); 193 | roots.set(n, r1); 194 | } 195 | } 196 | } 197 | 198 | /** 199 | * Create a doubly-linked list of nodes with one way connections and then 200 | * remove the support from root edges 201 | * 202 | * @param n a number proportional to the number of edges 203 | * @param m1 if one root edge should be retained 204 | */ 205 | public static void DoublyLinkedList(int n, boolean m1) { 206 | List roots = new ArrayList<>(); 207 | for (int i = 0; i < n; i++) { 208 | Root r = new Root(adv); 209 | roots.add(r); 210 | } 211 | shuffle(roots); 212 | for (int i = 0; i < n; i++) { 213 | Root r = roots.get(i); 214 | if (i + 1 < n) { 215 | Root rnext = roots.get(i + 1); 216 | r.get().createEdge(rnext.getId(),adv); 217 | } 218 | if (i - 1 >= 0) { 219 | Root rprev = roots.get(i - 1); 220 | r.get().createEdge(rprev.getId(),adv); 221 | } 222 | } 223 | for (int i = 0; i < n; i++) { 224 | if (m1 && i + 1 == n) { 225 | break; 226 | } 227 | roots.get(i).set(null,adv); 228 | } 229 | Message.runAll(); 230 | } 231 | 232 | public static void main(String[] args) throws Exception { 233 | try { 234 | // Require that assertions are enabled 235 | assert false; 236 | throw new Error("Enable assertions"); 237 | } catch (AssertionError ae) { 238 | } 239 | System.out.printf("Congest Mode=%s%n", Message.CONGEST_mode ? "on" : "off"); 240 | String test = Props.get("test"); 241 | String size = Props.get("size"); 242 | String fileloc = Props.get("fileloc"); 243 | if (test.equals("file-input")) { 244 | System.out.println("fileloc=" + fileloc); 245 | } 246 | System.out.println("test=" + test); 247 | System.out.println("size=" + size); 248 | System.out.flush(); 249 | int sizeI = Integer.parseInt(size); 250 | if (test.equals("file-input")) { 251 | System.out.println("File Input is chosen."); 252 | System.out.println("Input file location: " + fileloc); 253 | SimulationExecutor sim = new SimulationExecutor(fileloc); 254 | } else if (test.equals("cycle")) { 255 | CycleTest(sizeI, false); 256 | } else if (test.equals("cyclem1")) { 257 | CycleTest(sizeI, true); 258 | } else if (test.equals("dcycle")) { 259 | DoubleCycleTest(sizeI, false); 260 | } else if (test.equals("dcyclem1")) { 261 | DoubleCycleTest(sizeI, true); 262 | } else if (test.equals("dlink")) { 263 | DoublyLinkedList(sizeI, false); 264 | } else if (test.equals("dlinkm1")) { 265 | DoublyLinkedList(sizeI, true); 266 | } else if (test.equals("clique")) { 267 | CliqueTest(sizeI, false); 268 | } else if (test.equals("cliquem1")) { 269 | CliqueTest(sizeI, true); 270 | } else if (test.equals("grid")) { 271 | GridTest(sizeI, false); 272 | } else if (test.equals("gridm1")) { 273 | GridTest(sizeI, true); 274 | } else if (test.equals("rand")) { 275 | RandTest(sizeI, false); 276 | } else if (test.equals("randm1")) { 277 | RandTest(sizeI, true); 278 | } else { 279 | System.err.println("Unknown test type: "+test); 280 | System.exit(2); 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/SimulationExecutor.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileInputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintStream; 7 | import java.util.HashMap; 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | import java.util.ArrayList; 13 | import java.util.regex.Pattern; 14 | import java.util.regex.Matcher; 15 | 16 | public final class SimulationExecutor { 17 | 18 | Adversary adv = new Adversary(); 19 | 20 | // Parses the input file and runs the simulation. 21 | public SimulationExecutor(String fileloc) throws Exception { 22 | roots = new HashMap<>(); 23 | // Open the file 24 | FileInputStream fstream = new FileInputStream(fileloc); 25 | BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); 26 | String strLine; 27 | int lineNo = 1; 28 | // Read File Line By Line 29 | while ((strLine = br.readLine()) != null) { 30 | // Print the content on the console 31 | if (Here.VERBOSE) { 32 | System.out.println("Processing line: " + strLine); 33 | } 34 | if (!parseAndPerform(strLine, lineNo)) { 35 | System.out.println("Input file is not compilable!"); 36 | return; 37 | } 38 | lineNo++; 39 | } 40 | // Close the input stream 41 | br.close(); 42 | // Show summary information if we're done 43 | if(Message.msgs.size()==0) 44 | Message.runAll(); 45 | else 46 | Message.stateOfNodes(); 47 | pendingMessages(); 48 | } 49 | 50 | public void pendingMessages() { 51 | Here.bar("Pending Messages"); 52 | int count = 0; 53 | for(Message m : Message.msgs) { 54 | if(!m.done()) { 55 | System.out.println("m="+m+" node: "+Node.nodeMap.get(m.recipient)); 56 | count++; 57 | } 58 | } 59 | if(count == 0) 60 | System.out.println("None"); 61 | } 62 | 63 | // Parses CREATE statements and performs necessary action. 64 | public void createStatement(List tokens, int lineNo) { 65 | System.out.println("create: "+tokens); 66 | assert tokens.size() >= 2 : " Line : " + lineNo + " error. Create statement syntax is CREATE ."; 67 | Node prev = null; 68 | for(int i=1;i 0 : " Line : " + lineNo + " error. Node Id cannot be less 0 or negative number. "; 71 | Node node = Node.nodeMap.get(id); 72 | if(node == null) { 73 | node = new Node(id); 74 | if(prev != null) 75 | node.weight = prev.weight+1; 76 | } 77 | assert node.id == id; 78 | if(i == 1) { 79 | if(roots.get(id)==null) 80 | roots.put(id, new Root(adv,node)); 81 | else 82 | assert tokens.size() > 2 : "Create statement does nothing: line="+lineNo; 83 | } else { 84 | prev.createEdge(id,adv); 85 | } 86 | 87 | prev = node; 88 | } 89 | } 90 | 91 | // Parses UNROOT statements and performs necessary action. 92 | public void unRootNode(List tokens, int lineNo) { 93 | int id = Integer.parseInt(tokens.get(2)); 94 | assert id > 0 : " Line : " + lineNo + " error. Node Id cannot be less 0 or negative number. line="+lineNo; 95 | Root node = roots.get(id); 96 | assert node != null : "No edge from 0->"+id+" exists: line="+lineNo; 97 | assert node.get() != null : "Edge 0->"+id+" is already deleted: line="+lineNo; 98 | node.set(null,adv); 99 | } 100 | 101 | public void processRunAll(List tokens, int lineNo) { 102 | Message.runAll(); 103 | } 104 | 105 | public void processCheckStat(List tokens, int lineNo) { 106 | Message.checkStat(); 107 | } 108 | 109 | 110 | // runmsg lines are parsed, checked and executed. 111 | public void processMsgId(List tokens, int lineNo) { 112 | assert tokens.size() == 3 : "Line: " + lineNo 113 | + " error. runmsg is the syntaxt for the statement."; 114 | int nodeId = Integer.parseInt(tokens.get(1)); 115 | int msgId = Integer.parseInt(tokens.get(2)); 116 | assert nodeId > 0 && msgId >= 0 : "Line: " + lineNo 117 | + " error. nodeId or msg Id must be positive number."; 118 | try { 119 | Message.runMsg(nodeId, msgId); 120 | } catch(NoSuchMessage nsm) { 121 | throw new NoSuchMessage(String.format("%s %s %s",tokens.get(0),tokens.get(1),tokens.get(2))); 122 | } 123 | } 124 | 125 | // EDGE lines are parsed, checked and executed. 126 | public void createEdge(List tokens, int lineNo) { 127 | assert tokens.size() == 3 : "Line: " + lineNo 128 | + " error. EDGE is the syntaxt for the statement."; 129 | int sourceNode = Integer.parseInt(tokens.get(1)); 130 | int destNode = Integer.parseInt(tokens.get(2)); 131 | if(sourceNode == 0) { 132 | boolean found = false; 133 | Root r = roots.get(destNode); 134 | if(r != null && r.get() != null) 135 | throw new RuntimeException("A root edge to node to "+destNode+" already exists: line="+lineNo); 136 | for(Root root : roots.values()) { 137 | Node node = root.get(); 138 | if(node != null) { 139 | if(node.id == destNode) 140 | found = true; 141 | for(Integer edge : node.edges) { 142 | if(edge == destNode) 143 | found = true; 144 | } 145 | if(found) break; 146 | } 147 | } 148 | if(!found) 149 | throw new RuntimeException( 150 | "To add a root edge to a Node N, there must be a node M such that 0 -> M -> N. line="+lineNo); 151 | if(r == null) r = new Root(adv); 152 | r.set(Node.nodeMap.get(destNode),adv); 153 | roots.put(destNode,r); 154 | } else if(sourceNode > 0) { 155 | assert destNode > 0 : "Line: " + lineNo 156 | + " error. dest node cannot be root node (0) or negative number"; 157 | Node source = roots.get(sourceNode).get(); 158 | if(source == null) 159 | throw new RuntimeException("edge 0->"+sourceNode+" is required"); 160 | Node dest = roots.get(destNode).get(); 161 | if(dest == null) 162 | throw new RuntimeException("edge 0->"+destNode+" is required"); 163 | source.createEdge(destNode,adv); 164 | } else { 165 | throw new RuntimeException("Source node cannot be negative. line="+lineNo); 166 | } 167 | } 168 | 169 | // DELEDGE lines are parsed, checked and executed. 170 | public void deleteEdge(List tokens, int lineNo) { 171 | assert tokens.size() == 3 : "Line: " + lineNo 172 | + " error. EDGE is the syntaxt for the statement: line="+lineNo; 173 | int sourceNode = Integer.parseInt(tokens.get(1)); 174 | int destNode = Integer.parseInt(tokens.get(2)); 175 | if(sourceNode == 0) { 176 | unRootNode(tokens,lineNo); 177 | return; 178 | } 179 | assert sourceNode > 0 && destNode > 0 : "Line: " + lineNo 180 | + " error. source or dest node cannot be root node (0) or negative number: line="+lineNo; 181 | Root root = roots.get(sourceNode); 182 | assert root != null : "No edge from the root to node "+sourceNode+" exists: line="+lineNo; 183 | Node source = root.get(); 184 | if(source == null) 185 | throw new RuntimeException("No edge from a root to node id=" + sourceNode + ": line="+lineNo); 186 | boolean success = source.removeEdge(destNode, adv); 187 | assert success : "Remove non-existent edge"; 188 | } 189 | 190 | static Pattern noopPat = Pattern.compile("^\\s*(#.*|$)"); 191 | static Pattern msgPat = Pattern.compile("^\\s*(\\w+)\\s*(\\d+)\\s*->\\s*(\\d+)"); 192 | static Pattern parse = Pattern.compile("^\\s*(\\w+)(?:\\s+(\\d+)(?:\\s*->\\s*(?:\\d+))*|)"); 193 | static Pattern arrow = Pattern.compile("->\\s*(\\d+)"); 194 | 195 | // Parses individual lines and delegates the action to particular action 196 | // methods. 197 | public boolean parseAndPerform(String strLine, int lineNo) { 198 | List tokens = new ArrayList<>(); 199 | Matcher mtok = parse.matcher(strLine); 200 | if(mtok.matches()) { 201 | int count = 0; 202 | for(int i=0;i roots; 265 | } 266 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Message.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Random; 8 | 9 | public abstract class Message { 10 | 11 | private static int msg_seq = 1; 12 | public final static boolean CONGEST_mode = 13 | Props.get("CONGEST_mode").equals("yes"); 14 | final int msg_id = msg_seq++; 15 | final int sender, recipient; 16 | private boolean done; 17 | boolean action = true; 18 | 19 | Message(int s, int r) { 20 | sender = s; 21 | recipient = r; 22 | } 23 | 24 | public boolean isDone() { 25 | return done; 26 | } 27 | 28 | static int roundCount = 0; 29 | static int messageCount = 0; 30 | 31 | public void run() { 32 | assert !done : this; 33 | done = true; 34 | Node r = Node.nodeMap.get(recipient); 35 | if (Here.VERBOSE) { 36 | System.out.printf("Before %s: %s%n", sendStr(), r); 37 | } 38 | r.preCheck(sender, action); 39 | runTask(r); 40 | if (Here.VERBOSE) { 41 | System.out.printf("After %s: %s%n", sendStr(), r); 42 | } 43 | r.postCheck(sender, action, this instanceof IncrMessage); 44 | messageCount++; 45 | } 46 | 47 | public abstract void runTask(Node n); 48 | 49 | public String getName() { 50 | String nm = getClass().getName(); 51 | int b = nm.lastIndexOf('.') + 1; 52 | int e = nm.indexOf("Message"); 53 | return nm.substring(b, e); 54 | } 55 | 56 | final static Random RAND = new Random(); 57 | 58 | static { 59 | int s = RAND.nextInt(10000); 60 | String seedStr = Props.get("seed"); 61 | if (seedStr != null) { 62 | s = Integer.parseInt(seedStr); 63 | } 64 | System.out.printf("seed=%d%n", s); 65 | RAND.setSeed(s); 66 | } 67 | 68 | /** 69 | * The global message table. Once messages are enqueued, they run in a 70 | * completely random order. 71 | */ 72 | static MessageQueue msgs = new MessagesOvertake(Message.CONGEST_mode); 73 | // static MessageQueue msgs = new MessageDoNotOvertake(); 74 | 75 | public String sendStr() { 76 | return String.format("%s(mid=%d,%d->%d)", getName(), msg_id, sender, recipient); 77 | } 78 | 79 | public static void send(Message m) { 80 | StackTraceElement[] elems = new Throwable().getStackTrace(); 81 | StackTraceElement elem = null; 82 | if(elems.length > 2) { 83 | elem = elems[2]; 84 | } else { 85 | elem = elems[elems.length-1]; 86 | } 87 | if (Here.VERBOSE) { 88 | System.out.printf(" -->%s / (%s:%d)%n", m.sendStr(), elem.getFileName(), elem.getLineNumber()); 89 | } 90 | msgs.sendMessage(m); 91 | } 92 | 93 | /** 94 | * Run a single message 95 | * 96 | * @return 97 | */ 98 | public static boolean runOne() { 99 | if (CONGEST_mode) { 100 | return runOneRound(); 101 | } 102 | Message m = msgs.nextToRun(); 103 | if (m == null) { 104 | return false; 105 | } 106 | m.run(); 107 | return true; 108 | } 109 | 110 | static int timeStep = 1; 111 | 112 | /** 113 | * Run one message randomly chosen in each node 114 | * @return true if a message was run 115 | */ 116 | public static boolean runOneRound() { 117 | List mails = msgs.nextRoundToRun(); 118 | if (mails.isEmpty()) { 119 | return false; 120 | } else { 121 | if (Here.VERBOSE) { 122 | System.out.printf("Time Step=%d%n", timeStep++); 123 | } 124 | roundCount++; 125 | for (Message msg : mails) { 126 | msg.run(); 127 | } 128 | return true; 129 | } 130 | } 131 | 132 | /** 133 | * Send the current message, but don't wait for it to complete. 134 | */ 135 | public void queueMe() { 136 | assert sender == 0 || Node.nodeMap.get(sender) != null; 137 | assert Node.nodeMap.get(recipient) != null : "No such object " + recipient; 138 | if(this instanceof HasAdversary) { 139 | HasAdversary ha = (HasAdversary)this; 140 | Adversary adv = ha.adversary(); 141 | if(adv != null) { 142 | if(adv.msg != null) 143 | adv.msg.mwait(); 144 | adv.msg = this; 145 | } 146 | } 147 | send(this); 148 | } 149 | 150 | void mwait() { 151 | if (CONGEST_mode) { 152 | while (!isDone()) { 153 | boolean success = runOneRound(); 154 | assert success; 155 | } 156 | } else { 157 | while (!isDone()) { 158 | boolean success = runOne(); 159 | assert success; 160 | } 161 | } 162 | } 163 | 164 | static void checkCounts(Map counts, Node node) { 165 | List nodesToCheck = new ArrayList<>(); 166 | List moreNodesToCheck = new ArrayList<>(); 167 | nodesToCheck.add(node); 168 | while (true) { 169 | for (Node n : nodesToCheck) { 170 | checkCounts(counts, n, moreNodesToCheck); 171 | } 172 | if (moreNodesToCheck.size() == 0) { 173 | break; 174 | } else { 175 | nodesToCheck = moreNodesToCheck; 176 | moreNodesToCheck = new ArrayList<>(); 177 | } 178 | } 179 | } 180 | 181 | static void checkCounts(Map counts, Node node, List nodesToCheck) { 182 | Node.Counts c0 = counts.get(node.id); 183 | if (c0.marked) { 184 | return; 185 | } 186 | c0.marked = true; 187 | for (Integer edge : node.edges) { 188 | if (edge != null) { 189 | Node target = Node.nodeMap.get(edge); 190 | Node.Counts c = counts.get(target.id); 191 | if (c == null) { 192 | counts.put(target.id, c = new Node.Counts()); 193 | } 194 | if (node.weight < target.weight) { 195 | c.strong++; 196 | } else { 197 | c.weak++; 198 | } 199 | System.out.println("link => " + target.id + " c=" + c); 200 | // checkCounts(counts,target); 201 | nodesToCheck.add(target); 202 | } 203 | } 204 | } 205 | 206 | /** 207 | * Start from the roots and check the strong and weak counts of all nodes 208 | * and make sure they are correct. 209 | */ 210 | static void checkCounts() { 211 | Here.bar("Counts"); 212 | Map counts = new HashMap<>(); 213 | for (Root root : Root.roots) { 214 | Node node = root.get(); 215 | if (node == null) { 216 | continue; 217 | } 218 | Node.Counts c = counts.get(node.id); 219 | if (c == null) { 220 | counts.put(node.id, c = new Node.Counts()); 221 | } 222 | c.strong++; 223 | // c.marked=true; 224 | System.out.println("id=" + node.id + " " + c); 225 | Message.checkCounts(counts, node); 226 | } 227 | stateOfNodes(); 228 | for (Node node : Node.nodeMap.values()) { 229 | Node.Counts c = counts.get(node.id); 230 | if (node.cd != null) { 231 | assert node.cd.state == CollectorState.dead_state : "FAILURE: Node is neither recovered nor dead."; 232 | 233 | if (c == null) { 234 | assert node.strong_count == 0 : "strong count on deleted node: " + node; 235 | assert node.weak_count == 0 : "weak count on deleted node " + node; 236 | } else { 237 | assert node.strong_count == c.strong : String.format("%d: %d != %d", node.id, node.strong_count, 238 | c.strong); 239 | assert node.weak_count == c.weak : String.format("%d: %d != %d", node.id, node.weak_count, c.weak); 240 | } 241 | } else { 242 | assert node.strong_count > 0 : "strong count = 0 on live node " + node; 243 | assert c != null : node; 244 | assert c.strong == node.strong_count : "Bad strong: " + c + " != " + node; 245 | assert c.weak == node.weak_count : "Bad weak: " + c + " != " + node; 246 | assert c.marked; 247 | } 248 | } 249 | } 250 | 251 | static void stateOfNodes() { 252 | Here.bar("State of nodes"); 253 | for (Node node : Node.nodeMap.values()) { 254 | if (node.cd == null || node.cd.state != CollectorState.dead_state) { 255 | System.out.println(node); 256 | } 257 | } 258 | } 259 | 260 | static int edgeCount() { 261 | int edges = 0; 262 | for (Node node : Node.nodeMap.values()) { 263 | for (Integer edge : node.edges) { 264 | if (edge != null) { 265 | edges++; 266 | } 267 | } 268 | for (Integer edge : node.del_edges) { 269 | if (edge != null) { 270 | edges++; 271 | } 272 | } 273 | } 274 | return edges; 275 | } 276 | 277 | /** 278 | * Execute all messages. 279 | */ 280 | public static int runAll() { 281 | int rcount = roundCount; 282 | int mcount = messageCount; 283 | int edges = edgeCount(); 284 | 285 | while (runOne()) 286 | ; 287 | Here.bar("Collection Summary"); 288 | System.out.printf("Number of edges: %d%n", edges); 289 | System.out.printf("Number of rounds to converge: %d/%d%n", roundCount - rcount, roundCount); 290 | System.out.printf("Number of messages to converge: %d/%d%n", messageCount - mcount, messageCount); 291 | Message.checkCounts(); 292 | Message.markAndSweep(); 293 | return rcount; 294 | } 295 | 296 | /** 297 | * Execute msg specified 298 | */ 299 | public static void runMsg(int nodeId, int msgId) { 300 | Message msg = msgs.getMessage(nodeId, msgId); 301 | if(msg == null) 302 | throw new NoSuchMessage(); 303 | msg.run(); 304 | } 305 | 306 | /** 307 | * Performs post collection checks 308 | */ 309 | public static void checkStat(){ 310 | Message.checkCounts(); 311 | Message.markAndSweep(); 312 | } 313 | 314 | private static void markAndSweep() { 315 | for (Node node : Node.nodeMap.values()) { 316 | node.marked = false; 317 | } 318 | for (Root root : Root.roots) { 319 | if (root.get() != null) { 320 | markAndSweep(root.get()); 321 | } 322 | } 323 | for (Node node : Node.nodeMap.values()) { 324 | if (node.marked) { 325 | assert node.cd == null && node.strong_count > 0 : "" + node; 326 | } else { 327 | assert node.cd.state == CollectorState.dead_state && node.cd.wait_count == 0; 328 | } 329 | } 330 | } 331 | 332 | private static void markAndSweep(Node startNode) { 333 | List nodesToSweep = new ArrayList<>(); 334 | List moreNodesToSweep = new ArrayList<>(); 335 | nodesToSweep.add(startNode); 336 | while (true) { 337 | for (Node node : nodesToSweep) { 338 | markAndSweep(node, moreNodesToSweep); 339 | } 340 | if (moreNodesToSweep.size() == 0) { 341 | break; 342 | } else { 343 | nodesToSweep = moreNodesToSweep; 344 | moreNodesToSweep = new ArrayList<>(); 345 | } 346 | } 347 | } 348 | 349 | private static void markAndSweep(Node node, List nodesToSweep) { 350 | if (node.marked) { 351 | return; 352 | } 353 | node.marked = true; 354 | for (Integer edge : node.edges) { 355 | if (edge != null) { 356 | Node edgeNode = node.nodeMap.get(edge); 357 | if (!edgeNode.marked) { 358 | nodesToSweep.add(edgeNode); 359 | } 360 | } 361 | } 362 | for (Integer edge : node.del_edges) { 363 | if (edge != null) { 364 | Node edgeNode = node.nodeMap.get(edge); 365 | if (!edgeNode.marked) { 366 | nodesToSweep.add(edgeNode); 367 | } 368 | } 369 | } 370 | } 371 | 372 | public static int count() { 373 | return msgs.size(); 374 | } 375 | 376 | public String toString() { 377 | if(this instanceof CidMessage) { 378 | CidMessage c = (CidMessage)this; 379 | return String.format("%s %d->%d (cd=%s)",shortName(),sender,recipient,c.getCid()); 380 | } else { 381 | return String.format("%s %d->%d",shortName(),sender,recipient); 382 | } 383 | } 384 | 385 | public boolean done() { return done; } 386 | 387 | public abstract String shortName(); 388 | } 389 | -------------------------------------------------------------------------------- /python/SWPR-1.py: -------------------------------------------------------------------------------- 1 | import random 2 | msgs = [] 3 | id_seq = -1 4 | 5 | nodes = {} 6 | 7 | def rm1(value,li): 8 | new_li = [] 9 | found = False 10 | for i in range(len(li)): 11 | if not found and li[i] == value: 12 | found = True 13 | else: 14 | new_li += [li[i]] 15 | assert found 16 | return new_li 17 | 18 | def prmsg(msg): 19 | print("Message:",end=" ") 20 | msg_fields = ["mtype","weight","sender","target"] 21 | for k in msg: 22 | assert k in msg_fields 23 | for k in msg_fields: 24 | if k in msg: 25 | print(k,"=",str(msg[k]),sep="",end="") 26 | if k != "target": 27 | print(end=",") 28 | print() 29 | 30 | def node_info(): 31 | print() 32 | print("=" * 50) 33 | for node in nodes: 34 | if node > 0: 35 | print(nodes[node].info()) 36 | else: 37 | edges = {} 38 | for e in nodes[0].edges: 39 | edges[e.id]=1 40 | print("root=",[id for id in edges]) 41 | print("=" * 50) 42 | 43 | def mark_and_sweep(): 44 | for id in nodes: 45 | nodes[id].mark = False 46 | nodes[id].wc = 0 47 | nodes[id].sc = 0 48 | root = nodes[0] 49 | proc_set = [nodes[0]] 50 | while len(proc_set)>0: 51 | node = proc_set[0] 52 | del proc_set[0] 53 | if not node.mark: 54 | for n in node.edges: 55 | if node.weight < n.weight: 56 | n.sc += 1 57 | else: 58 | n.wc += 1 59 | proc_set += node.edges 60 | proc_set += node.deledges 61 | node.mark = True 62 | for id in nodes: 63 | if id == 0: 64 | continue 65 | node = nodes[id] 66 | if node.mark: 67 | assert node.strong_count > 0, node.info() 68 | assert node.state == "healthy", node.info() 69 | assert node.sc == node.strong_count, "sc=%d, %s" % (node.sc,node.info()) 70 | assert node.wc == node.weak_count, node.info() 71 | else: 72 | assert node.strong_count == 0, node.info() 73 | assert node.state == "dead", node.info() 74 | assert node.sc == 0, node.info() 75 | assert node.wc == 0, node.info() 76 | assert node.phantom_count == 0, node.info() 77 | 78 | class Node: 79 | def __init__(self,weight): 80 | global id_seq, nodes 81 | id_seq += 1 82 | self.id = id_seq 83 | self.weight = weight + 1 84 | self.max_weight = weight 85 | self.strong_count = 1 86 | self.weak_count = 0 87 | self.wait_count = 0 88 | self.phantom_count = 0 89 | self.state = "healthy" 90 | self.edges = [] 91 | self.deledges = [] 92 | self.parent = -1 93 | self.mark = False 94 | nodes[self.id] = self 95 | 96 | def __str__(self): 97 | return "Node(id=%d)" % self.id 98 | 99 | def send(self,msg): 100 | global msgs 101 | if "target" in msg: 102 | assert type(msg["target"]) != int 103 | print(" Send: ",end="") 104 | prmsg(msg) 105 | msgs += [msg] 106 | assert msg["target"] != None 107 | 108 | def send_all(self,mtype,sender): 109 | for node in self.edges: 110 | self.send({ 111 | "mtype":mtype, 112 | "weight":self.weight, 113 | "sender":self, 114 | "target":node 115 | }) 116 | if mtype != "infect": 117 | self.wait_count += 1 118 | self.state = mtype 119 | if self.parent < 0 and sender != None: 120 | self.parent = sender.id 121 | if self.wait_count == 0 and mtype != "infect": 122 | self.wait_count = 1 123 | self.ret() 124 | 125 | def incr(self,weight): 126 | if weight > self.max_weight: 127 | self.max_weight = weight 128 | if weight < self.weight: 129 | self.strong_count += 1 130 | else: 131 | self.weak_count += 1 132 | 133 | def info(self): 134 | if self.parent != None: 135 | sinit = str(self.parent) 136 | ids = [] 137 | for node in self.edges: 138 | ids += [node.id] 139 | return "Node(id=%d,weight=%d/%d,state=%s,strong=%d,weak=%d,phantom=%d,parent=%s,wait=%d,edges=%s)" % \ 140 | (self.id,self.weight,self.max_weight,self.state, \ 141 | self.strong_count,self.weak_count,self.phantom_count, \ 142 | self.parent,self.wait_count,str(ids)) 143 | 144 | def edge(self,node): 145 | global msgs 146 | assert node.id != 0 147 | print() 148 | print("Create Edge:",str(self)) 149 | self.send({ 150 | "mtype":"incr", 151 | "weight":self.weight, 152 | "target":node 153 | }) 154 | self.edges += [node] 155 | self.mwait() 156 | 157 | def create(self): 158 | node = Node(self.weight) 159 | self.edges += [node] 160 | return node 161 | 162 | def deledge(self,node): 163 | global msgs 164 | print() 165 | print("Delete Edge:",str(self)) 166 | self.send({ 167 | "mtype":"decr", 168 | "weight":self.weight, 169 | "target":node 170 | }) 171 | self.edges = rm1(node,self.edges) 172 | self.mwait() 173 | 174 | # ===START OF ALGO=== 175 | def decr(self,weight): 176 | global msgs 177 | if weight < self.weight: 178 | self.strong_count -= 1 179 | assert self.strong_count >= 0 180 | else: 181 | self.weak_count -= 1 182 | assert self.weak_count >= 0 183 | if self.strong_count == 0: 184 | self.parent = 0 185 | self.send_all("phantom",None) 186 | self.toggle() 187 | 188 | def toggle(self): 189 | print(" Toggle") 190 | self.strong_count = self.weak_count 191 | self.weak_count = 0 192 | self.weight = self.max_weight + 1 193 | 194 | def phantom(self,weight,sender): 195 | if weight < self.weight: 196 | self.strong_count -= 1 197 | assert self.strong_count >= 0 198 | else: 199 | self.weak_count -= 1 200 | assert self.weak_count >= 0 201 | self.phantom_count += 1 202 | if self.strong_count == 0 and self.state == "healthy": 203 | self.send_all("phantom",sender) 204 | self.toggle() 205 | else: 206 | self.return_msg(sender) 207 | 208 | def recover(self,weight,sender): 209 | if self.state == "phantom" and self.parent < 0: 210 | if self.strong_count > 0: 211 | self.send_all("build",sender) 212 | else: 213 | self.send_all("recover",sender) 214 | else: 215 | self.return_msg(sender) 216 | 217 | def build(self,weight,sender): 218 | if self.state in ["phantom","recover"] and self.strong_count == 0 and self.weak_count == 0: 219 | self.weight = weight + 1 220 | self.max_weight = weight 221 | if weight < self.weight: 222 | self.strong_count += 1 223 | else: 224 | self.weak_count += 1 225 | if weight > self.max_weight: 226 | self.max_weight = weight 227 | self.phantom_count -= 1 228 | if self.state in ["phantom","recover"] and self.parent < 0: 229 | self.send_all("build",sender) 230 | else: 231 | self.return_msg(sender) 232 | if self.parent < 0 and self.phantom_count == 0: 233 | self.healthy() 234 | 235 | def ret(self): 236 | self.wait_count -= 1 237 | assert self.wait_count >= 0 238 | if self.wait_count > 0: 239 | return 240 | if self.parent == 0: 241 | if self.state == "phantom": 242 | if self.strong_count > 0 or self.weak_count > 0: 243 | self.send_all("build",None) 244 | else: 245 | self.send_all("recover",None) 246 | elif self.state == "build": 247 | self.healthy() 248 | elif self.state == "recover": 249 | if self.strong_count > 0: 250 | self.send_all("build",None) 251 | else: 252 | self.send_all("infect",None) 253 | self.edges = [] 254 | else: 255 | if self.state == "recover" and self.strong_count > 0: 256 | self.send_all("build",-1) 257 | elif self.parent > 0: 258 | self.return_msg(nodes[self.parent]) 259 | self.parent = -1 260 | if self.wait_count == 0 and self.parent <= 0: 261 | if self.strong_count > 0 and self.phantom_count == 0: 262 | self.healthy() 263 | elif self.strong_count == 0 and self.weak_count == 0 and self.phantom_count == 0: 264 | assert self.wait_count == 0 265 | self.send_all("infect",None) 266 | self.state = "dead" 267 | 268 | def infect(self): 269 | self.phantom_count -= 1 270 | assert self.phantom_count >= 0 271 | if self.strong_count == 0 and self.weak_count == 0: 272 | self.send_all("infect",None) 273 | self.deledges += [e for e in self.edges] 274 | self.edges = [] 275 | if self.phantom_count == 0: 276 | self.state = "dead" 277 | elif self.phantom_count == 0: 278 | self.healthy() 279 | # ===END OF ALGO=== 280 | 281 | def healthy(self): 282 | self.state = "healthy" 283 | self.parent = -1 284 | 285 | def return_msg(self,target): 286 | self.send({ 287 | "mtype":"return", 288 | "target":target 289 | }) 290 | 291 | def mwait(self): 292 | global msgs 293 | while len(msgs) > 0: 294 | n = random.randrange(0,len(msgs)) 295 | msg = msgs[n] 296 | del msgs[n] 297 | target = msg["target"] 298 | print() 299 | prmsg(msg) 300 | print(" Before:",target.info()) 301 | if msg["mtype"] == "phantom": 302 | msg["target"].phantom(msg["weight"],msg["sender"]) 303 | elif msg["mtype"] == "recover": 304 | msg["target"].recover(msg["weight"],msg["sender"]) 305 | elif msg["mtype"] == "build": 306 | msg["target"].build(msg["weight"],msg["sender"]) 307 | elif msg["mtype"] == "return": 308 | msg["target"].ret() 309 | elif msg["mtype"] == "decr": 310 | msg["target"].decr(msg["weight"]) 311 | elif msg["mtype"] == "incr": 312 | msg["target"].incr(msg["weight"]) 313 | elif msg["mtype"] == "infect": 314 | msg["target"].infect() 315 | else: 316 | raise Exception(msg["mtype"]) 317 | print(" After: ",target.info()) 318 | node_info() 319 | mark_and_sweep() 320 | 321 | root = Node(-1) 322 | 323 | def dlink(n): 324 | nlist = [] 325 | for i in range(n): 326 | nlist += [root.create()] 327 | for i in range(1,n): 328 | nlist[i-1].edge(nlist[i]) 329 | nlist[i].edge(nlist[i-1]) 330 | for i in range(n): 331 | root.deledge(nlist[i]) 332 | 333 | def rand(n): 334 | nlist = [] 335 | m = int(n/2) 336 | for i in range(m): 337 | nlist += [root.create()] 338 | for i in range(1,n): 339 | r1 = random.randrange(0,m) 340 | r2 = random.randrange(0,m) 341 | nlist[r1].edge(nlist[r2]) 342 | for i in range(m): 343 | root.deledge(nlist[i]) 344 | 345 | def cycle(n): 346 | nlist = [] 347 | for i in range(n): 348 | nlist += [root.create()] 349 | for i in range(n): 350 | nx = (i+1)%n 351 | nlist[i].edge(nlist[nx]) 352 | for i in range(n): 353 | root.deledge(nlist[i]) 354 | 355 | def connected(n): 356 | m = 2 357 | while m*(m-1) < n: 358 | m += 1 359 | nlist = [] 360 | for i in range(m): 361 | nlist += [root.create()] 362 | count = 0 363 | for off in range(1,m): 364 | for i in range(m): 365 | if count >= n: 366 | break 367 | nx = (i+off)%m 368 | nlist[i].edge(nlist[nx]) 369 | count += 1 370 | for i in range(m): 371 | root.deledge(nlist[i]) 372 | 373 | def grid(n): 374 | m = 2 375 | while 4*(m-1)**2 < n: 376 | m += 1 377 | nlist = [] 378 | for i in range(m): 379 | sublist = [] 380 | for j in range(m): 381 | sublist += [root.create()] 382 | nlist += [sublist] 383 | count = 0 384 | for i in range(1,m): 385 | for j in range(m): 386 | if count >= n: 387 | break 388 | nlist[i-1][j].edge(nlist[i][j]) 389 | count += 1 390 | if count >= n: 391 | break 392 | nlist[i][j].edge(nlist[i-1][j]) 393 | count += 1 394 | for i in range(m): 395 | for j in range(1,m): 396 | if count >= n: 397 | break 398 | nlist[i][j-1].edge(nlist[i][j]) 399 | count += 1 400 | if count >= n: 401 | break 402 | nlist[i][j].edge(nlist[i][j-1]) 403 | count += 1 404 | for i in range(m): 405 | for j in range(m): 406 | root.deledge(nlist[i][j]) 407 | 408 | tmap = { 409 | "cycle":cycle, 410 | "dlink":dlink, 411 | "connected":connected, 412 | "grid":grid, 413 | "rand":rand 414 | } 415 | 416 | for sz in range(2,70): 417 | #for seed in range(53,54): 418 | for seed in range(0,100): 419 | for test in ["rand","cycle","dlink","connected","grid"]: 420 | random.seed(seed) 421 | nodes = {0:root} 422 | id_seq = 0 423 | assert len(msgs)==0 424 | print("TEST: %s, size=%d, seed=%d" % (test,sz,seed)) 425 | tmap[test](sz) 426 | -------------------------------------------------------------------------------- /src/edu/lsu/cct/distgc/Node.java: -------------------------------------------------------------------------------- 1 | package edu.lsu.cct.distgc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class Node { 9 | 10 | final boolean CHK_COUNTS = Props.get("CheckCounts").equals("yes"); 11 | static Map nodeMap = new HashMap<>(); 12 | 13 | LocalState lstate = new LocalState(); 14 | 15 | static int id_seq = 1; 16 | final int id; 17 | 18 | int weight = 1, max_weight, strong_count, weak_count; 19 | CollectionData cd; 20 | List edges = new ArrayList<>(); 21 | 22 | // Keep track of edges deleted by the SWP 23 | // method so Mark & Sweep can follow them 24 | List del_edges = new ArrayList<>(); 25 | // Used by the Mark & Sweep collector for 26 | // verification purposes 27 | public boolean marked; 28 | 29 | public Node() { 30 | while(nodeMap.get(id_seq) != null) 31 | id_seq++; 32 | this.id = id_seq++; 33 | nodeMap.put(this.id, this); 34 | } 35 | 36 | public Node(int id) { 37 | if(nodeMap.containsKey(id)) 38 | throw new RuntimeException("Duplicate node"); 39 | this.id = id; 40 | nodeMap.put(this.id, this); 41 | } 42 | 43 | void preCheck(int sender, boolean isReturn) { 44 | assert cd == null || cd.state != CollectorState.dead_state : this; 45 | lstate = new LocalState(); 46 | lstate.old_weight = weight; 47 | if (cd != null) { 48 | lstate.original_parent = cd.parent; 49 | } 50 | } 51 | 52 | void postCheck(int sender, boolean action,boolean isIncr) { 53 | int parent = -1; 54 | if (cd != null) { 55 | parent = cd.parent; 56 | } 57 | if (parent < 0) { 58 | parent = lstate.sent_to_parent; 59 | } 60 | // If this assertion triggers, it means 61 | // that return_to_parent() should have 62 | // been called. 63 | boolean parent_sent_as_sender = (lstate.returned_to_sender && cd != null && cd.parent == sender); 64 | if (!isIncr && ready() && cd != null && cd.parent > 0 && !parent_sent_as_sender) { 65 | assert false; 66 | } 67 | if (action) { 68 | if (cd != null && lstate.original_parent != cd.parent && cd.parent == sender) 69 | ; // the parent was set by this message 70 | else if (lstate.returned_to_parent) 71 | ; else // If the message was one of: Phantomize, Recover, Build and 72 | // the sender did not become the parent, a return should be 73 | // sent to the sender. 74 | { 75 | assert lstate.returned_to_sender; 76 | } 77 | } 78 | lstate = null; 79 | } 80 | 81 | /** 82 | * Used by checkCounts() for bookkeeping. 83 | * 84 | * @author sbrandt 85 | * 86 | */ 87 | static class Counts { 88 | 89 | int strong, weak; 90 | boolean marked; 91 | 92 | public String toString() { 93 | return "strong=" + strong + ", weak=" + weak + ", marked=" + marked; 94 | } 95 | } 96 | 97 | // \Procedure{OnEdgeCreation}{sender_weight,is_phantom_edge,sender_cid} 98 | public void incr(int sender,int sender_weight, boolean is_phantom_edge, CID sender_cid) { 99 | if (is_phantom_edge) { 100 | if (cd == null) { 101 | cd = new CollectionData(sender_cid); 102 | cd.parent = sender; 103 | } 104 | cd.phantom_count++; 105 | if(CHK_COUNTS) assert cd.rcc >= 0; 106 | if(CHK_COUNTS) assert cd.phantom_count >= cd.rcc; 107 | if(cd.phantom_count == 0 && cd.rcc == 0) { 108 | cd = null; 109 | } 110 | } else if (sender_weight < weight) { 111 | strong_count++; 112 | } else { 113 | weak_count++; 114 | } 115 | if (sender_weight > max_weight) { 116 | max_weight = sender_weight; 117 | } 118 | } 119 | 120 | public boolean has_edges() { 121 | return edges.size() > 0; 122 | } 123 | 124 | public int createEdge(int rid,Adversary adv) { 125 | edges.add(rid); 126 | Message m = null; 127 | if (cd != null) { 128 | m = new IncrMessage(id, rid, weight, phantom_flag(), cd.getCid(),adv); 129 | } else { 130 | m = new IncrMessage(id, rid, weight, false, null,adv); 131 | } 132 | m.queueMe(); 133 | return rid; 134 | } 135 | 136 | boolean has_no_outgoing_edges() { 137 | return out().size() == 0; 138 | } 139 | 140 | // \Procedure{OnEdgeDeletion}{sender,sender_weight,is_phantom_edge,sender_cid} 141 | public void decr(int sender, int sender_weight, boolean phantom_flag, CID sender_cid) { 142 | if (phantom_flag) { 143 | if(cd == null) { 144 | cd = new CollectionData(sender_cid); 145 | } 146 | cd.phantom_count--; 147 | if (sender_cid.equals(cd.getCid())) { 148 | cd.rcc--; 149 | } 150 | if(CHK_COUNTS) assert cd.rcc >= 0; 151 | if(CHK_COUNTS) assert cd.phantom_count >= cd.rcc; 152 | if(CHK_COUNTS) assert cd.phantom_count >= 0; 153 | } else if (sender_weight < weight) { 154 | strong_count--; 155 | if(CHK_COUNTS) assert strong_count >= 0; 156 | } else { 157 | weak_count--; 158 | if(CHK_COUNTS) assert weak_count >= 0; 159 | } 160 | if (cd == null) { 161 | if (strong_count > 0) { 162 | return; 163 | } else if (weak_count > 0) { 164 | if (has_no_outgoing_edges()) { 165 | toggle(); 166 | } else { 167 | cd = new CollectionData(id); 168 | toggle(); 169 | PhantomizeAll(sender); 170 | } 171 | } else { 172 | delete_outgoing_edges(null); 173 | cd = new CollectionData(id); 174 | cd.state = CollectorState.dead_state; 175 | } 176 | } else { 177 | return_to_parent_force(); 178 | cd.setCid(new CID(cd.getCid().majorId + 1, id, 0)); 179 | cd.parent = 0; 180 | if (cd.wait_count == 0) { 181 | action(sender); 182 | } 183 | } 184 | } 185 | 186 | // \Procedure{Toggle}{} 187 | private void toggle() { 188 | if (weak_count > 0 && strong_count == 0) { 189 | Here.log("toggle"); 190 | strong_count = weak_count; 191 | weak_count = 0; 192 | weight = max_weight + 1; 193 | } 194 | } 195 | 196 | // \Procedure{Phantomize}{sender,sender_cid} 197 | public void phantomize(int sender, int w, CID sender_cid) { 198 | if (w < weight) { 199 | strong_count--; 200 | if(CHK_COUNTS) assert strong_count >= 0 : "Negative strong count"; 201 | } else { 202 | weak_count--; 203 | if(CHK_COUNTS) assert weak_count >= 0 : "Negative weak count"; 204 | } 205 | boolean do_action = cidCheck(sender, sender_cid); 206 | if (lstate.parent_was_set) { 207 | cd.recv = CollectorState.phantom_state; 208 | } 209 | cd.phantom_count++; 210 | if (do_action) { 211 | if (!is_initiator()) { 212 | action(sender); 213 | } 214 | } 215 | return_to_sender(sender); 216 | if(cd.phantom_count == 0 && strong_count == 0 && weak_count == 0 && cd.wait_count == 0) { 217 | delete_outgoing_edges(null); 218 | cd.state = CollectorState.dead_state; 219 | } 220 | } 221 | 222 | public boolean removeEdge(Integer edge,Adversary adv) { 223 | int i = edges.indexOf(edge); 224 | if(i >= 0) { 225 | boolean ph = false; 226 | CID mcid = null; 227 | if(phantom_flag()) { 228 | ph = true; 229 | mcid = cd.getCid(); 230 | } 231 | Message m = new DecrMessage(id, edge, weight, ph, mcid, adv); 232 | m.queueMe(); 233 | edges.remove(edge); 234 | return true; 235 | } 236 | return false; 237 | } 238 | 239 | void delete_outgoing_edges(Adversary adv) { 240 | for (int i = 0; i < edges.size(); i++) { 241 | Integer edge = edges.get(i); 242 | Message m = null; 243 | if (cd == null) { 244 | m = new DecrMessage(id, edge, weight, false, null,adv); 245 | } else { 246 | m = new DecrMessage(id, edge, weight, phantom_flag(), cd.getCid(),adv); 247 | } 248 | m.queueMe(); 249 | } 250 | edges.clear(); 251 | } 252 | 253 | // \Procedure{PhantomizeAll}{sender_weight,is_phantom_edge,sender_cid} 254 | private void PhantomizeAll(int sender) { 255 | assert strong_count == 0 || lstate.old_weight < weight; 256 | if (phantom_flag()) { 257 | ClaimAll(); 258 | return; 259 | } 260 | assert cd.wait_count == 0; 261 | assert cd.state == CollectorState.healthy_state || cd.state == CollectorState.build_state; 262 | cd.state = CollectorState.phantom_state; 263 | for (Integer edge : edges) { 264 | Message m = new PhantomizeMessage(id, edge, lstate.old_weight, cd.getCid()); 265 | m.queueMe(); 266 | cd.wait_count++; 267 | } 268 | if (cd.wait_count == 0) { 269 | cd.state = CollectorState.healthy_state; 270 | return_to_parent(); 271 | if(strong_count > 0 && cd.phantom_count == 0 && cd.rcc == 0) { 272 | return_to_sender(sender); 273 | cd = null; 274 | } else { 275 | cd.incrRCC = false; 276 | } 277 | } else { 278 | cd.incrRCC = false; 279 | } 280 | } 281 | 282 | // \Procedure{Claim}{sender,sender_cid} 283 | public void claim(int sender, CID sender_cid) { 284 | boolean do_action = cidCheck(sender, sender_cid); 285 | if (lstate.parent_was_set) { 286 | cd.recv = CollectorState.phantom_state; 287 | } 288 | if (do_action) { 289 | if (!is_initiator()) { 290 | action(sender); 291 | } 292 | } 293 | return_to_sender(sender); 294 | } 295 | 296 | // \Procedure{ClaimAll}{} 297 | public void ClaimAll() { 298 | assert cd.wait_count == 0; 299 | assert phantom_flag() : this.toString(); 300 | cd.state = CollectorState.phantom_state; 301 | for (Integer edge : edges) { 302 | Message m = new ClaimMessage(id, edge, cd.getCid()); 303 | m.queueMe(); 304 | cd.wait_count++; 305 | } 306 | if (cd.wait_count == 0) { 307 | return_to_parent(); 308 | } 309 | cd.incrRCC = false; 310 | } 311 | 312 | // \Procedure{Recover}{sender_cid,sender,incrRCC,mandate} 313 | public void recover(CID sender_cid, int sender, boolean incrRCC) { 314 | // If any strong count , also return. 315 | // Put at the top of every operation 316 | 317 | boolean incr = CID.lessThan(cd.getCid(), sender_cid); 318 | boolean do_action = cidCheck(sender, sender_cid); 319 | if (lstate.parent_was_set) { 320 | cd.recv = CollectorState.recover_state; 321 | } 322 | if (incrRCC && CID.equals(sender_cid, cd.getCid()) && cd.phantom_count > 0) { 323 | cd.rcc++; 324 | } 325 | if(CHK_COUNTS) assert cd.rcc >= 0; 326 | if(CHK_COUNTS) assert cd.phantom_count >= cd.rcc; 327 | if (do_action) { 328 | cd.incrRCC = false; 329 | if (!is_initiator()) { 330 | action(sender); 331 | } 332 | } 333 | return_to_sender(sender); 334 | } 335 | 336 | // \Procedure{RecoverAll}{} 337 | private void RecoverAll() { 338 | if (cd.incrRCC) { 339 | ClaimAll(); 340 | return; 341 | } 342 | assert cd.wait_count == 0; 343 | assert cd.getCid() != null; 344 | assert phantom_flag(); 345 | boolean incrRCC = !(CID.equals(cd.recoverCid, cd.getCid())); 346 | cd.state = CollectorState.recover_state; 347 | cd.recoverCid = cd.getCid(); 348 | for (Integer edge : edges) { 349 | cd.wait_count++; 350 | Message m = new RecoverMessage(id, edge, cd.getCid(), incrRCC); 351 | m.queueMe(); 352 | } 353 | cd.incrRCC = false; 354 | if (ready()) { 355 | // cd.wait_count = 1; 356 | return_to_parent(); 357 | // ret(cd.start_over); 358 | } 359 | } 360 | 361 | // \Procedure{Build}{sender_weight,sender_cid,sender,decrRCC,mandate} 362 | public void build(int sender, int sender_weight, CID sender_cid, boolean incrRCC, boolean mandate, boolean decrRCC) { 363 | 364 | assert cd != null; 365 | 366 | if(CHK_COUNTS) assert cd.phantom_count > 0; 367 | 368 | // Add check on strong and weak count here. If they aren't zero, 369 | // changing the weights could mess everything up. 370 | if (cd != null && phantom_flag() && strong_count == 0 && weak_count == 0) { 371 | Here.log("weight adjust"); 372 | weight = sender_weight + 1; 373 | max_weight = sender_weight; 374 | } 375 | if (sender_weight < weight) { 376 | strong_count++; 377 | } else { 378 | weak_count++; 379 | } 380 | if (sender_weight > max_weight) { 381 | max_weight = sender_weight; 382 | } 383 | cd.phantom_count--; 384 | 385 | boolean do_action = cidCheck(sender, sender_cid); 386 | if (lstate.parent_was_set) { 387 | cd.recv = CollectorState.build_state; 388 | } 389 | if (lstate.in_collection_message && decrRCC) { 390 | cd.rcc--; 391 | if(CHK_COUNTS) assert cd.rcc >= 0; 392 | } 393 | // If a lower CID rebuilds one of our links and 394 | // we're ready to go, we should go. 395 | if (ready() && cd.parent >= 0) { 396 | action(sender); 397 | return_to_sender(sender); 398 | return; 399 | } 400 | if (do_action) { 401 | if (!is_initiator()) { 402 | action(sender); 403 | } 404 | } 405 | return_to_sender(sender); 406 | } 407 | 408 | // \Procedure{BuildAll}{sender} 409 | private void BuildAll(int sender) { 410 | assert cd.wait_count == 0; 411 | if (!phantom_flag()) { 412 | if (!is_initiator()) { 413 | return_to_parent(); 414 | } 415 | return; 416 | } 417 | // boolean decrRCC = (cd.state == CollectorState.recover_state); 418 | boolean decrRCC = CID.equals(cd.recoverCid, cd.getCid()); 419 | cd.recoverCid = null; 420 | cd.state = CollectorState.build_state; 421 | for (Integer edge : edges) { 422 | cd.wait_count++; 423 | Message m = new BuildMessage(id, edge, weight, cd.getCid(), cd.incrRCC, lstate.parent_was_set, decrRCC); 424 | m.queueMe(); 425 | } 426 | cd.incrRCC = false; 427 | if (ready()) { 428 | // cd.wait_count = 1; 429 | // ret(cd.start_over); 430 | return_to_parent(); 431 | return_to_sender(sender); 432 | cd = null; 433 | } 434 | } 435 | 436 | // \Procedure{plague}{sender,sender_cid} 437 | public void plague(int sender, CID sender_cid, boolean message) { 438 | cd.phantom_count--; 439 | if (CID.equals(sender_cid, cd.getCid())) { 440 | cd.rcc--; 441 | } 442 | if(CHK_COUNTS) assert cd.phantom_count >= 0; 443 | if(cd.phantom_count == cd.rcc && cd.wait_count == 0) { 444 | if (strong_count == 0 && weak_count == 0) { 445 | InfectAll(); 446 | return; 447 | } else if(cd.phantom_count == 0) { 448 | cd = null; 449 | } 450 | } 451 | } 452 | 453 | // \Procedure{InfectAll}{} 454 | public void InfectAll() { 455 | assert phantom_flag(); 456 | assert strong_count == 0 && weak_count == 0; 457 | for (int i = 0; i < edges.size(); i++) { // pseudo: for each edge 458 | Integer edge = edges.get(i); // pseudo: 459 | if (edge != null) { // pseudo: 460 | Message m = new PlagueMessage(id, edge, cd.getCid()); 461 | m.queueMe(); 462 | } // pseudo: 463 | del_edges.add(edge); // pseudo: set edge to null 464 | } 465 | edges.clear(); 466 | if (strong_count == 0 && weak_count == 0 && cd.phantom_count == 0 && cd.wait_count == 0) { 467 | cd.state = CollectorState.dead_state; 468 | } else { 469 | cd.state = CollectorState.infected_state; 470 | } 471 | } 472 | 473 | // \Procedure{Return}{start_over_cid} 474 | public void ret(CID start_over_cid) { 475 | assert cd != null : "Return message sent to healthy node"; 476 | cd.wait_count--; 477 | if (start_over_cid != null) { 478 | if (cd.start_over == null || CID.lessThan(cd.start_over, start_over_cid)) { 479 | cd.start_over = start_over_cid; 480 | } 481 | if (is_initiator() && CID.equals(start_over_cid, cd.getCid())) { 482 | CID mycid = cd.getCid(); 483 | cd.setCid(new CID(mycid.majorId, mycid.objId, mycid.minorId + 1)); 484 | } 485 | } 486 | if(CHK_COUNTS) assert cd.wait_count >= 0 : this; 487 | if (cd.wait_count == 0) { 488 | if (start_over_cid != null && is_initiator()) { 489 | if (!CID.equals(start_over_cid, cd.getCid())) { 490 | start_over_cid = null; 491 | } 492 | // Doesn't make sense, initiator has no parent 493 | // return_to_parent_force(true); 494 | CID c = cd.getCid(); 495 | cd.setCid(new CID(c.majorId, c.objId, c.minorId + 1)); 496 | if (cd.phantom_count == 0 && strong_count > 0 && ready()) { 497 | if (phantom_flag()) { 498 | BuildAll(-1); 499 | } else { 500 | return_to_sender(-1); 501 | cd = null; 502 | } 503 | } else if (phantom_flag()) { 504 | RecoverAll(); 505 | } else if (strong_count > 0) { 506 | BuildAll(-1); 507 | } else { 508 | toggle(); 509 | PhantomizeAll(-1); 510 | } 511 | } else { 512 | action(-1); 513 | } 514 | } else { 515 | CID mycid = cd.getCid(); 516 | if (CID.equals(mycid, start_over_cid)) { 517 | if (is_initiator()) { 518 | cd.setCid(new CID(mycid.majorId, mycid.objId, mycid.minorId + 1)); 519 | cd.parent = 0; 520 | if (cd.wait_count == 0) { 521 | action(-1); 522 | } 523 | } 524 | } 525 | } 526 | } 527 | 528 | void return_to_parent_force() { 529 | return_to_parent_base(cd.start_over, true); 530 | } 531 | 532 | void return_to_parent_force(CID start_over) { 533 | return_to_parent_base(start_over, true); 534 | } 535 | 536 | void return_to_parent(CID start_over) { 537 | return_to_parent_base(start_over, false); 538 | } 539 | 540 | // rocedure{Return_to_parent}{start_over_cid,force} 541 | private void return_to_parent_base(CID start_over_cid, boolean force) { 542 | if (!force && !ready()) { 543 | return; 544 | } 545 | if (cd.parent <= 0) { 546 | return; 547 | } 548 | Message msg = new RetMessage(id, cd.parent, start_over_cid); 549 | cd.start_over = null; 550 | msg.queueMe(); 551 | lstate.sent_to_parent = cd.parent; 552 | cd.parent = -1; 553 | cd.recv = CollectorState.healthy_state; 554 | lstate.returned_to_parent = true; 555 | } 556 | 557 | void return_to_parent() { 558 | return_to_parent_base(cd.start_over, false); 559 | } 560 | 561 | // rocedure{Return_to_sender}{start_over_cid} 562 | private void return_to_sender(int sender) { 563 | if (cd == null) { 564 | // pseudo: pass 565 | } else if (cd != null && lstate.original_parent != cd.parent && cd.parent == sender && sender != -1) { 566 | // pseudo: pass 567 | } else if (lstate.returned_to_parent && cd != null && cd.parent == sender) { 568 | // pseudo: pass 569 | } else if (sender == -1) { 570 | // pseudo: pass 571 | } else if (sender != lstate.sent_to_parent) { 572 | Message msg = new RetMessage(id, sender, null); 573 | msg.queueMe(); 574 | lstate.returned_to_sender = true; 575 | } 576 | } 577 | 578 | private boolean is_initiator() { 579 | return cd != null && cd.parent == 0; 580 | } 581 | 582 | public List out() { 583 | int count = 0; 584 | List li = new ArrayList<>(); 585 | for (Integer edge : edges) { 586 | li.add(edge); 587 | } 588 | return li; 589 | } 590 | 591 | public String toString() { 592 | return String.format("id=%d wt/mx=%d/%d out=%s s,w=%d,%d", id, weight, max_weight, out(), strong_count, 593 | weak_count) + (cd == null ? ":" : cd.toString()); 594 | } 595 | 596 | // \Procedure{cidCheck}{} 597 | private boolean cidCheck(int sender, CID sender_cid) { 598 | 599 | // Put at the top of every operation 600 | if (cd == null) { 601 | if (sender_cid == null) { 602 | sender_cid = new CID(0, this.id, 0); 603 | } 604 | cd = new CollectionData(sender_cid); 605 | cd.parent = sender; 606 | lstate.parent_was_set = true; 607 | } else if (sender == 0) { 608 | // pseudo: pass 609 | assert sender_cid == null; 610 | } else if (CID.equals(sender_cid, cd.getCid())) { 611 | lstate.in_collection_message = true; 612 | if (cd.wait_count > 0) { 613 | return false; 614 | } 615 | if (cd.parent < 0) { 616 | cd.parent = sender; 617 | lstate.parent_was_set = true; 618 | } 619 | } else if (CID.lessThan(sender_cid, cd.getCid())) { 620 | // plague message, no return needed 621 | return false; 622 | } else if (cd.wait_count > 0) { 623 | if (!is_initiator()) { 624 | return_to_parent_force(cd.getCid()); 625 | } 626 | cd.parent = sender; 627 | lstate.parent_was_set = true; 628 | cd.setCid(sender_cid); 629 | cd.start_over = null; 630 | // If we updated the sender_cid, then previous recovers 631 | // are no longer good enough. We'll have to recover 632 | // again. 633 | if (cd.state == CollectorState.recover_state) { 634 | cd.state = CollectorState.phantom_state; 635 | } 636 | return false; 637 | } else if (CID.lessThan(cd.getCid(), sender_cid)) { 638 | assert sender != 0; 639 | if (cd.parent > 0) { 640 | return_to_parent_force(cd.getCid()); 641 | } else { 642 | cd.start_over = null; 643 | } 644 | cd.parent = sender; 645 | lstate.parent_was_set = true; 646 | cd.setCid(sender_cid); 647 | } 648 | return true; 649 | } 650 | 651 | // \Procedure{Ready}{sender_weight,is_phantom_edge,sender_cid} 652 | public boolean ready() { 653 | if (cd == null) { 654 | return true; 655 | } 656 | if (cd.wait_count > 0) { 657 | return false; 658 | } 659 | if (cd.rcc < cd.phantom_count) { 660 | if (is_initiator()) { 661 | if (cd.state == CollectorState.recover_state || cd.state == CollectorState.build_state) { 662 | return false; 663 | } 664 | } else if (cd.recv == CollectorState.recover_state || cd.recv == CollectorState.build_state) { 665 | return false; 666 | } 667 | } 668 | if(CHK_COUNTS) assert cd.rcc <= cd.phantom_count : this; 669 | return true; 670 | } 671 | 672 | // clearpage 673 | // \Procedure{actionInitiator}{sender} 674 | public void action_initiator(int sender) { 675 | if (ready()) { 676 | if (cd.state == CollectorState.healthy_state) { 677 | if (!phantom_flag() && lstate.old_weight < weight || strong_count == 0) { 678 | PhantomizeAll(sender); 679 | } 680 | } else if (cd.state == CollectorState.phantom_state) { 681 | if (strong_count > 0) { 682 | BuildAll(sender); 683 | } else if (has_no_outgoing_edges() && weak_count == 0 && cd.phantom_count == 0) { 684 | cd.state = CollectorState.dead_state; 685 | } else if(weak_count == 0) { 686 | RecoverAll(); 687 | } 688 | } else if (cd.state == CollectorState.recover_state) { 689 | if (strong_count == 0) { 690 | InfectAll(); 691 | } else { 692 | BuildAll(sender); 693 | } 694 | } else if (cd.state == CollectorState.infected_state) { 695 | if (cd.phantom_count == 0 && strong_count == 0 && weak_count == 0) { 696 | cd.state = CollectorState.dead_state; 697 | } 698 | } else if (cd.phantom_count == 0) { 699 | return_to_sender(sender); 700 | if(strong_count == 0 && weak_count == 0) { 701 | PhantomizeAll(sender); 702 | } else { 703 | cd = null; 704 | } 705 | } 706 | } else if (phantom_flag()) { 707 | if (cd.incrRCC) { 708 | ClaimAll(); 709 | } 710 | } else if (strong_count == 0) { 711 | PhantomizeAll(sender); 712 | } else if (!phantom_flag()) { 713 | if (strong_count == 0) { 714 | PhantomizeAll(sender); 715 | } else { // pseudo: 716 | } 717 | } else { // pseudo: 718 | } 719 | } 720 | 721 | // \Procedure{action}{sender} 722 | public void action(int sender) { 723 | if (cd == null) { 724 | return; 725 | } 726 | toggle(); 727 | assert cd.wait_count == 0; 728 | if (lstate.old_weight < weight) { 729 | PhantomizeAll(sender); 730 | } else if (is_initiator()) { 731 | action_initiator(sender); 732 | } else if (cd.recv == CollectorState.healthy_state) { 733 | if(cd.phantom_count == 0 && cd.rcc == 0 && cd.wait_count == 0) { 734 | return_to_sender(sender); 735 | cd = null; 736 | } 737 | } else if (cd.recv == CollectorState.phantom_state) { 738 | if (!phantom_flag() && (lstate.old_weight < weight || strong_count == 0)) { 739 | PhantomizeAll(sender); 740 | } else if (cd.incrRCC && phantom_flag()) { 741 | ClaimAll(); 742 | } else { 743 | return_to_parent(); 744 | } 745 | } else if (cd.recv == CollectorState.recover_state) { 746 | if (cd.state != CollectorState.recover_state) { 747 | if (strong_count > 0) { 748 | BuildAll(sender); 749 | } else if (phantom_flag()) { 750 | RecoverAll(); 751 | } else { 752 | PhantomizeAll(sender); 753 | } 754 | } else if (strong_count > 0) { 755 | BuildAll(sender); 756 | } else if (weak_count > 0) { 757 | PhantomizeAll(sender); 758 | } else { 759 | return_to_parent(); 760 | } 761 | } else if (cd.recv == CollectorState.build_state) { 762 | if (phantom_flag()) { 763 | BuildAll(sender); 764 | } else { 765 | return_to_parent(); 766 | if (cd.phantom_count == 0) { 767 | return_to_sender(sender); 768 | cd = null; 769 | } 770 | } 771 | } else if (cd.recv == CollectorState.infected_state) { 772 | if (cd.state != CollectorState.infected_state) { 773 | if (phantom_flag()) { 774 | InfectAll(); 775 | } 776 | } 777 | if (ready() && strong_count == 0 && weak_count == 0 && cd.phantom_count == 0) { 778 | cd.state = CollectorState.dead_state; 779 | } 780 | } 781 | } 782 | 783 | // \Procedure{Phantom_Flag}{} 784 | private boolean phantom_flag() { 785 | if(cd == null) { 786 | return false; 787 | } else { 788 | return cd.state == CollectorState.phantom_state || cd.state == CollectorState.recover_state || cd.state == CollectorState.infected_state; 789 | } 790 | } 791 | } 792 | -------------------------------------------------------------------------------- /plots/grid-CONGEST-shuffle-a0-rnds.ps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-3.0 2 | %%Title: plots/grid-CONGEST-shuffle-a0-rnds.ps 3 | %%Creator: matplotlib version 1.5.2rc2, http://matplotlib.org/ 4 | %%CreationDate: Thu Apr 19 12:03:36 2018 5 | %%Orientation: portrait 6 | %%DocumentPaperSizes: letter 7 | %%BoundingBox: 18 180 594 612 8 | %%Pages: 1 9 | %%EndComments 10 | %%BeginProlog 11 | /mpldict 8 dict def 12 | mpldict begin 13 | /m { moveto } bind def 14 | /l { lineto } bind def 15 | /r { rlineto } bind def 16 | /c { curveto } bind def 17 | /cl { closepath } bind def 18 | /box { 19 | m 20 | 1 index 0 r 21 | 0 exch r 22 | neg 0 r 23 | cl 24 | } bind def 25 | /clipbox { 26 | box 27 | clip 28 | newpath 29 | } bind def 30 | %!PS-Adobe-3.0 Resource-Font 31 | %%Title: Bitstream Vera Sans 32 | %%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. 33 | %%Creator: Converted from TrueType to type 3 by PPR 34 | 25 dict begin 35 | /_d{bind def}bind def 36 | /_m{moveto}_d 37 | /_l{lineto}_d 38 | /_cl{closepath eofill}_d 39 | /_c{curveto}_d 40 | /_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d 41 | /_e{exec}_d 42 | /FontName /BitstreamVeraSans-Roman def 43 | /PaintType 0 def 44 | /FontMatrix[.001 0 0 .001 0 0]def 45 | /FontBBox[-183 -236 1287 928]def 46 | /FontType 3 def 47 | /Encoding [ /space /parenleft /parenright /asterisk /comma /period /slash /zero /one /two /three /four /five /nine /colon /equal /C /E /F /G /N /O /R /S /T /a /b /c /d /e /f /g /i /l /m /n /o /p /r /s /t /u /x ] def 48 | /FontInfo 10 dict dup begin 49 | /FamilyName (Bitstream Vera Sans) def 50 | /FullName (Bitstream Vera Sans) def 51 | /Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.) def 52 | /Weight (Roman) def 53 | /Version (Release 1.10) def 54 | /ItalicAngle 0.0 def 55 | /isFixedPitch false def 56 | /UnderlinePosition -213 def 57 | /UnderlineThickness 143 def 58 | end readonly def 59 | /CharStrings 43 dict dup begin 60 | /space{318 0 0 0 0 0 _sc 61 | }_d 62 | /parenleft{390 0 86 -131 310 759 _sc 63 | 310 759 _m 64 | 266 683 234 609 213 536 _c 65 | 191 463 181 389 181 314 _c 66 | 181 238 191 164 213 91 _c 67 | 234 17 266 -56 310 -131 _c 68 | 232 -131 _l 69 | 183 -54 146 20 122 94 _c 70 | 98 168 86 241 86 314 _c 71 | 86 386 98 459 122 533 _c 72 | 146 607 182 682 232 759 _c 73 | 310 759 _l 74 | _cl}_d 75 | /parenright{390 0 80 -131 304 759 _sc 76 | 80 759 _m 77 | 158 759 _l 78 | 206 682 243 607 267 533 _c 79 | 291 459 304 386 304 314 _c 80 | 304 241 291 168 267 94 _c 81 | 243 20 206 -54 158 -131 _c 82 | 80 -131 _l 83 | 123 -56 155 17 177 91 _c 84 | 198 164 209 238 209 314 _c 85 | 209 389 198 463 177 536 _c 86 | 155 609 123 683 80 759 _c 87 | _cl}_d 88 | /asterisk{500 0 30 286 470 742 _sc 89 | 470 609 _m 90 | 295 514 _l 91 | 470 419 _l 92 | 442 371 _l 93 | 278 470 _l 94 | 278 286 _l 95 | 222 286 _l 96 | 222 470 _l 97 | 58 371 _l 98 | 30 419 _l 99 | 205 514 _l 100 | 30 609 _l 101 | 58 657 _l 102 | 222 558 _l 103 | 222 742 _l 104 | 278 742 _l 105 | 278 558 _l 106 | 442 657 _l 107 | 470 609 _l 108 | _cl}_d 109 | /comma{318 0 77 -115 220 124 _sc 110 | 117 124 _m 111 | 220 124 _l 112 | 220 40 _l 113 | 140 -115 _l 114 | 77 -115 _l 115 | 117 40 _l 116 | 117 124 _l 117 | _cl}_d 118 | /period{318 0 107 0 210 124 _sc 119 | 107 124 _m 120 | 210 124 _l 121 | 210 0 _l 122 | 107 0 _l 123 | 107 124 _l 124 | _cl}_d 125 | /slash{337 0 0 -92 337 729 _sc 126 | 254 729 _m 127 | 337 729 _l 128 | 83 -92 _l 129 | 0 -92 _l 130 | 254 729 _l 131 | _cl}_d 132 | /zero{636 0 66 -13 570 742 _sc 133 | 318 664 _m 134 | 267 664 229 639 203 589 _c 135 | 177 539 165 464 165 364 _c 136 | 165 264 177 189 203 139 _c 137 | 229 89 267 64 318 64 _c 138 | 369 64 407 89 433 139 _c 139 | 458 189 471 264 471 364 _c 140 | 471 464 458 539 433 589 _c 141 | 407 639 369 664 318 664 _c 142 | 318 742 _m 143 | 399 742 461 709 505 645 _c 144 | 548 580 570 486 570 364 _c 145 | 570 241 548 147 505 83 _c 146 | 461 19 399 -13 318 -13 _c 147 | 236 -13 173 19 130 83 _c 148 | 87 147 66 241 66 364 _c 149 | 66 486 87 580 130 645 _c 150 | 173 709 236 742 318 742 _c 151 | _cl}_d 152 | /one{636 0 110 0 544 729 _sc 153 | 124 83 _m 154 | 285 83 _l 155 | 285 639 _l 156 | 110 604 _l 157 | 110 694 _l 158 | 284 729 _l 159 | 383 729 _l 160 | 383 83 _l 161 | 544 83 _l 162 | 544 0 _l 163 | 124 0 _l 164 | 124 83 _l 165 | _cl}_d 166 | /two{{636 0 73 0 536 742 _sc 167 | 192 83 _m 168 | 536 83 _l 169 | 536 0 _l 170 | 73 0 _l 171 | 73 83 _l 172 | 110 121 161 173 226 239 _c 173 | 290 304 331 346 348 365 _c 174 | 380 400 402 430 414 455 _c 175 | 426 479 433 504 433 528 _c 176 | 433 566 419 598 392 622 _c 177 | 365 646 330 659 286 659 _c 178 | 255 659 222 653 188 643 _c 179 | 154 632 117 616 78 594 _c 180 | 78 694 _l 181 | 118 710 155 722 189 730 _c 182 | 223 738 255 742 284 742 _c 183 | }_e{359 742 419 723 464 685 _c 184 | 509 647 532 597 532 534 _c 185 | 532 504 526 475 515 449 _c 186 | 504 422 484 390 454 354 _c 187 | 446 344 420 317 376 272 _c 188 | 332 227 271 164 192 83 _c 189 | _cl}_e}_d 190 | /three{{636 0 76 -13 556 742 _sc 191 | 406 393 _m 192 | 453 383 490 362 516 330 _c 193 | 542 298 556 258 556 212 _c 194 | 556 140 531 84 482 45 _c 195 | 432 6 362 -13 271 -13 _c 196 | 240 -13 208 -10 176 -4 _c 197 | 144 1 110 10 76 22 _c 198 | 76 117 _l 199 | 103 101 133 89 166 81 _c 200 | 198 73 232 69 268 69 _c 201 | 330 69 377 81 409 105 _c 202 | 441 129 458 165 458 212 _c 203 | 458 254 443 288 413 312 _c 204 | 383 336 341 349 287 349 _c 205 | }_e{202 349 _l 206 | 202 430 _l 207 | 291 430 _l 208 | 339 430 376 439 402 459 _c 209 | 428 478 441 506 441 543 _c 210 | 441 580 427 609 401 629 _c 211 | 374 649 336 659 287 659 _c 212 | 260 659 231 656 200 650 _c 213 | 169 644 135 635 98 623 _c 214 | 98 711 _l 215 | 135 721 170 729 203 734 _c 216 | 235 739 266 742 296 742 _c 217 | 370 742 429 725 473 691 _c 218 | 517 657 539 611 539 553 _c 219 | 539 513 527 479 504 451 _c 220 | 481 423 448 403 406 393 _c 221 | _cl}_e}_d 222 | /four{636 0 49 0 580 729 _sc 223 | 378 643 _m 224 | 129 254 _l 225 | 378 254 _l 226 | 378 643 _l 227 | 352 729 _m 228 | 476 729 _l 229 | 476 254 _l 230 | 580 254 _l 231 | 580 172 _l 232 | 476 172 _l 233 | 476 0 _l 234 | 378 0 _l 235 | 378 172 _l 236 | 49 172 _l 237 | 49 267 _l 238 | 352 729 _l 239 | _cl}_d 240 | /five{{636 0 77 -13 549 729 _sc 241 | 108 729 _m 242 | 495 729 _l 243 | 495 646 _l 244 | 198 646 _l 245 | 198 467 _l 246 | 212 472 227 476 241 478 _c 247 | 255 480 270 482 284 482 _c 248 | 365 482 429 459 477 415 _c 249 | 525 370 549 310 549 234 _c 250 | 549 155 524 94 475 51 _c 251 | 426 8 357 -13 269 -13 _c 252 | 238 -13 207 -10 175 -6 _c 253 | 143 -1 111 6 77 17 _c 254 | 77 116 _l 255 | 106 100 136 88 168 80 _c 256 | 199 72 232 69 267 69 _c 257 | }_e{323 69 368 83 401 113 _c 258 | 433 143 450 183 450 234 _c 259 | 450 284 433 324 401 354 _c 260 | 368 384 323 399 267 399 _c 261 | 241 399 214 396 188 390 _c 262 | 162 384 135 375 108 363 _c 263 | 108 729 _l 264 | _cl}_e}_d 265 | /nine{{636 0 63 -13 566 742 _sc 266 | 110 15 _m 267 | 110 105 _l 268 | 134 93 159 84 185 78 _c 269 | 210 72 235 69 260 69 _c 270 | 324 69 374 90 408 134 _c 271 | 442 178 462 244 468 334 _c 272 | 448 306 424 284 396 269 _c 273 | 367 254 335 247 300 247 _c 274 | 226 247 168 269 126 313 _c 275 | 84 357 63 417 63 494 _c 276 | 63 568 85 628 129 674 _c 277 | 173 719 232 742 306 742 _c 278 | 390 742 455 709 499 645 _c 279 | 543 580 566 486 566 364 _c 280 | }_e{566 248 538 157 484 89 _c 281 | 429 21 356 -13 264 -13 _c 282 | 239 -13 214 -10 189 -6 _c 283 | 163 -2 137 5 110 15 _c 284 | 306 324 _m 285 | 350 324 385 339 411 369 _c 286 | 437 399 450 441 450 494 _c 287 | 450 546 437 588 411 618 _c 288 | 385 648 350 664 306 664 _c 289 | 262 664 227 648 201 618 _c 290 | 175 588 162 546 162 494 _c 291 | 162 441 175 399 201 369 _c 292 | 227 339 262 324 306 324 _c 293 | _cl}_e}_d 294 | /colon{337 0 117 0 220 517 _sc 295 | 117 124 _m 296 | 220 124 _l 297 | 220 0 _l 298 | 117 0 _l 299 | 117 124 _l 300 | 117 517 _m 301 | 220 517 _l 302 | 220 393 _l 303 | 117 393 _l 304 | 117 517 _l 305 | _cl}_d 306 | /equal{838 0 106 172 732 454 _sc 307 | 106 454 _m 308 | 732 454 _l 309 | 732 372 _l 310 | 106 372 _l 311 | 106 454 _l 312 | 106 255 _m 313 | 732 255 _l 314 | 732 172 _l 315 | 106 172 _l 316 | 106 255 _l 317 | _cl}_d 318 | /C{{698 0 56 -13 644 742 _sc 319 | 644 673 _m 320 | 644 569 _l 321 | 610 599 575 622 537 638 _c 322 | 499 653 460 661 418 661 _c 323 | 334 661 270 635 226 584 _c 324 | 182 533 160 460 160 364 _c 325 | 160 268 182 194 226 143 _c 326 | 270 92 334 67 418 67 _c 327 | 460 67 499 74 537 90 _c 328 | 575 105 610 128 644 159 _c 329 | 644 56 _l 330 | 609 32 572 15 534 4 _c 331 | 496 -7 455 -13 412 -13 _c 332 | 302 -13 215 20 151 87 _c 333 | }_e{87 154 56 246 56 364 _c 334 | 56 481 87 573 151 641 _c 335 | 215 708 302 742 412 742 _c 336 | 456 742 497 736 535 725 _c 337 | 573 713 610 696 644 673 _c 338 | _cl}_e}_d 339 | /E{632 0 98 0 568 729 _sc 340 | 98 729 _m 341 | 559 729 _l 342 | 559 646 _l 343 | 197 646 _l 344 | 197 430 _l 345 | 544 430 _l 346 | 544 347 _l 347 | 197 347 _l 348 | 197 83 _l 349 | 568 83 _l 350 | 568 0 _l 351 | 98 0 _l 352 | 98 729 _l 353 | _cl}_d 354 | /F{575 0 98 0 517 729 _sc 355 | 98 729 _m 356 | 517 729 _l 357 | 517 646 _l 358 | 197 646 _l 359 | 197 431 _l 360 | 486 431 _l 361 | 486 348 _l 362 | 197 348 _l 363 | 197 0 _l 364 | 98 0 _l 365 | 98 729 _l 366 | _cl}_d 367 | /G{{775 0 56 -13 693 742 _sc 368 | 595 104 _m 369 | 595 300 _l 370 | 434 300 _l 371 | 434 381 _l 372 | 693 381 _l 373 | 693 68 _l 374 | 655 40 613 20 567 7 _c 375 | 521 -6 472 -13 420 -13 _c 376 | 306 -13 216 20 152 86 _c 377 | 88 152 56 245 56 364 _c 378 | 56 482 88 575 152 642 _c 379 | 216 708 306 742 420 742 _c 380 | 467 742 512 736 555 724 _c 381 | 598 712 638 695 674 673 _c 382 | 674 568 _l 383 | 637 598 598 621 557 637 _c 384 | 516 653 473 661 428 661 _c 385 | }_e{338 661 271 636 227 586 _c 386 | 182 536 160 462 160 364 _c 387 | 160 265 182 191 227 141 _c 388 | 271 91 338 67 428 67 _c 389 | 462 67 493 70 521 76 _c 390 | 549 82 573 91 595 104 _c 391 | _cl}_e}_d 392 | /N{748 0 98 0 650 729 _sc 393 | 98 729 _m 394 | 231 729 _l 395 | 554 119 _l 396 | 554 729 _l 397 | 650 729 _l 398 | 650 0 _l 399 | 517 0 _l 400 | 194 610 _l 401 | 194 0 _l 402 | 98 0 _l 403 | 98 729 _l 404 | _cl}_d 405 | /O{787 0 56 -13 731 742 _sc 406 | 394 662 _m 407 | 322 662 265 635 223 582 _c 408 | 181 528 160 456 160 364 _c 409 | 160 272 181 199 223 146 _c 410 | 265 92 322 66 394 66 _c 411 | 465 66 522 92 564 146 _c 412 | 606 199 627 272 627 364 _c 413 | 627 456 606 528 564 582 _c 414 | 522 635 465 662 394 662 _c 415 | 394 742 _m 416 | 496 742 577 707 639 639 _c 417 | 700 571 731 479 731 364 _c 418 | 731 248 700 157 639 89 _c 419 | 577 21 496 -13 394 -13 _c 420 | 291 -13 209 21 148 89 _c 421 | 86 157 56 248 56 364 _c 422 | 56 479 86 571 148 639 _c 423 | 209 707 291 742 394 742 _c 424 | _cl}_d 425 | /R{{695 0 98 0 666 729 _sc 426 | 444 342 _m 427 | 465 334 486 319 506 296 _c 428 | 526 272 546 240 566 199 _c 429 | 666 0 _l 430 | 560 0 _l 431 | 467 187 _l 432 | 443 235 419 268 397 284 _c 433 | 374 300 343 308 304 308 _c 434 | 197 308 _l 435 | 197 0 _l 436 | 98 0 _l 437 | 98 729 _l 438 | 321 729 _l 439 | 404 729 466 711 507 677 _c 440 | 548 642 569 589 569 519 _c 441 | 569 473 558 434 537 404 _c 442 | 515 374 484 353 444 342 _c 443 | 197 648 _m 444 | 197 389 _l 445 | 321 389 _l 446 | }_e{368 389 404 400 428 422 _c 447 | 452 444 465 476 465 519 _c 448 | 465 561 452 593 428 615 _c 449 | 404 637 368 648 321 648 _c 450 | 197 648 _l 451 | _cl}_e}_d 452 | /S{{635 0 66 -13 579 742 _sc 453 | 535 705 _m 454 | 535 609 _l 455 | 497 627 462 640 429 649 _c 456 | 395 657 363 662 333 662 _c 457 | 279 662 237 651 208 631 _c 458 | 179 610 165 580 165 542 _c 459 | 165 510 174 485 194 469 _c 460 | 213 452 250 439 304 429 _c 461 | 364 417 _l 462 | 437 403 491 378 526 343 _c 463 | 561 307 579 260 579 201 _c 464 | 579 130 555 77 508 41 _c 465 | 460 5 391 -13 300 -13 _c 466 | 265 -13 228 -9 189 -2 _c 467 | }_e{150 5 110 16 69 32 _c 468 | 69 134 _l 469 | 109 111 148 94 186 83 _c 470 | 224 71 262 66 300 66 _c 471 | 356 66 399 77 430 99 _c 472 | 460 121 476 152 476 194 _c 473 | 476 230 465 258 443 278 _c 474 | 421 298 385 313 335 323 _c 475 | 275 335 _l 476 | 201 349 148 372 115 404 _c 477 | 82 435 66 478 66 534 _c 478 | 66 598 88 649 134 686 _c 479 | 179 723 242 742 322 742 _c 480 | 356 742 390 739 426 733 _c 481 | 461 727 497 717 535 705 _c 482 | }_e{_cl}_e}_d 483 | /T{611 0 -2 0 614 729 _sc 484 | -2 729 _m 485 | 614 729 _l 486 | 614 646 _l 487 | 355 646 _l 488 | 355 0 _l 489 | 256 0 _l 490 | 256 646 _l 491 | -2 646 _l 492 | -2 729 _l 493 | _cl}_d 494 | /a{{613 0 60 -13 522 560 _sc 495 | 343 275 _m 496 | 270 275 220 266 192 250 _c 497 | 164 233 150 205 150 165 _c 498 | 150 133 160 107 181 89 _c 499 | 202 70 231 61 267 61 _c 500 | 317 61 357 78 387 114 _c 501 | 417 149 432 196 432 255 _c 502 | 432 275 _l 503 | 343 275 _l 504 | 522 312 _m 505 | 522 0 _l 506 | 432 0 _l 507 | 432 83 _l 508 | 411 49 385 25 355 10 _c 509 | 325 -5 287 -13 243 -13 _c 510 | 187 -13 142 2 109 33 _c 511 | 76 64 60 106 60 159 _c 512 | }_e{60 220 80 266 122 298 _c 513 | 163 329 224 345 306 345 _c 514 | 432 345 _l 515 | 432 354 _l 516 | 432 395 418 427 391 450 _c 517 | 364 472 326 484 277 484 _c 518 | 245 484 215 480 185 472 _c 519 | 155 464 127 453 100 439 _c 520 | 100 522 _l 521 | 132 534 164 544 195 550 _c 522 | 226 556 256 560 286 560 _c 523 | 365 560 424 539 463 498 _c 524 | 502 457 522 395 522 312 _c 525 | _cl}_e}_d 526 | /b{{635 0 91 -13 580 760 _sc 527 | 487 273 _m 528 | 487 339 473 390 446 428 _c 529 | 418 466 381 485 334 485 _c 530 | 286 485 249 466 222 428 _c 531 | 194 390 181 339 181 273 _c 532 | 181 207 194 155 222 117 _c 533 | 249 79 286 61 334 61 _c 534 | 381 61 418 79 446 117 _c 535 | 473 155 487 207 487 273 _c 536 | 181 464 _m 537 | 199 496 223 520 252 536 _c 538 | 281 552 316 560 356 560 _c 539 | 422 560 476 533 518 481 _c 540 | 559 428 580 359 580 273 _c 541 | }_e{580 187 559 117 518 65 _c 542 | 476 13 422 -13 356 -13 _c 543 | 316 -13 281 -5 252 10 _c 544 | 223 25 199 49 181 82 _c 545 | 181 0 _l 546 | 91 0 _l 547 | 91 760 _l 548 | 181 760 _l 549 | 181 464 _l 550 | _cl}_e}_d 551 | /c{{550 0 55 -13 488 560 _sc 552 | 488 526 _m 553 | 488 442 _l 554 | 462 456 437 466 411 473 _c 555 | 385 480 360 484 334 484 _c 556 | 276 484 230 465 198 428 _c 557 | 166 391 150 339 150 273 _c 558 | 150 206 166 154 198 117 _c 559 | 230 80 276 62 334 62 _c 560 | 360 62 385 65 411 72 _c 561 | 437 79 462 90 488 104 _c 562 | 488 21 _l 563 | 462 9 436 0 410 -5 _c 564 | 383 -10 354 -13 324 -13 _c 565 | 242 -13 176 12 128 64 _c 566 | }_e{79 115 55 185 55 273 _c 567 | 55 362 79 432 128 483 _c 568 | 177 534 244 560 330 560 _c 569 | 358 560 385 557 411 551 _c 570 | 437 545 463 537 488 526 _c 571 | _cl}_e}_d 572 | /d{{635 0 55 -13 544 760 _sc 573 | 454 464 _m 574 | 454 760 _l 575 | 544 760 _l 576 | 544 0 _l 577 | 454 0 _l 578 | 454 82 _l 579 | 435 49 411 25 382 10 _c 580 | 353 -5 319 -13 279 -13 _c 581 | 213 -13 159 13 117 65 _c 582 | 75 117 55 187 55 273 _c 583 | 55 359 75 428 117 481 _c 584 | 159 533 213 560 279 560 _c 585 | 319 560 353 552 382 536 _c 586 | 411 520 435 496 454 464 _c 587 | 148 273 _m 588 | 148 207 161 155 188 117 _c 589 | 215 79 253 61 301 61 _c 590 | }_e{348 61 385 79 413 117 _c 591 | 440 155 454 207 454 273 _c 592 | 454 339 440 390 413 428 _c 593 | 385 466 348 485 301 485 _c 594 | 253 485 215 466 188 428 _c 595 | 161 390 148 339 148 273 _c 596 | _cl}_e}_d 597 | /e{{615 0 55 -13 562 560 _sc 598 | 562 296 _m 599 | 562 252 _l 600 | 149 252 _l 601 | 153 190 171 142 205 110 _c 602 | 238 78 284 62 344 62 _c 603 | 378 62 412 66 444 74 _c 604 | 476 82 509 95 541 113 _c 605 | 541 28 _l 606 | 509 14 476 3 442 -3 _c 607 | 408 -9 373 -13 339 -13 _c 608 | 251 -13 182 12 131 62 _c 609 | 80 112 55 181 55 268 _c 610 | 55 357 79 428 127 481 _c 611 | 175 533 241 560 323 560 _c 612 | 397 560 455 536 498 489 _c 613 | }_e{540 441 562 377 562 296 _c 614 | 472 322 _m 615 | 471 371 457 410 431 440 _c 616 | 404 469 368 484 324 484 _c 617 | 274 484 234 469 204 441 _c 618 | 174 413 156 373 152 322 _c 619 | 472 322 _l 620 | _cl}_e}_d 621 | /f{352 0 23 0 371 760 _sc 622 | 371 760 _m 623 | 371 685 _l 624 | 285 685 _l 625 | 253 685 230 678 218 665 _c 626 | 205 652 199 629 199 595 _c 627 | 199 547 _l 628 | 347 547 _l 629 | 347 477 _l 630 | 199 477 _l 631 | 199 0 _l 632 | 109 0 _l 633 | 109 477 _l 634 | 23 477 _l 635 | 23 547 _l 636 | 109 547 _l 637 | 109 585 _l 638 | 109 645 123 690 151 718 _c 639 | 179 746 224 760 286 760 _c 640 | 371 760 _l 641 | _cl}_d 642 | /g{{635 0 55 -207 544 560 _sc 643 | 454 280 _m 644 | 454 344 440 395 414 431 _c 645 | 387 467 349 485 301 485 _c 646 | 253 485 215 467 188 431 _c 647 | 161 395 148 344 148 280 _c 648 | 148 215 161 165 188 129 _c 649 | 215 93 253 75 301 75 _c 650 | 349 75 387 93 414 129 _c 651 | 440 165 454 215 454 280 _c 652 | 544 68 _m 653 | 544 -24 523 -93 482 -139 _c 654 | 440 -184 377 -207 292 -207 _c 655 | 260 -207 231 -204 203 -200 _c 656 | 175 -195 147 -188 121 -178 _c 657 | }_e{121 -91 _l 658 | 147 -105 173 -115 199 -122 _c 659 | 225 -129 251 -133 278 -133 _c 660 | 336 -133 380 -117 410 -87 _c 661 | 439 -56 454 -10 454 52 _c 662 | 454 96 _l 663 | 435 64 411 40 382 24 _c 664 | 353 8 319 0 279 0 _c 665 | 211 0 157 25 116 76 _c 666 | 75 127 55 195 55 280 _c 667 | 55 364 75 432 116 483 _c 668 | 157 534 211 560 279 560 _c 669 | 319 560 353 552 382 536 _c 670 | 411 520 435 496 454 464 _c 671 | 454 547 _l 672 | 544 547 _l 673 | }_e{544 68 _l 674 | _cl}_e}_d 675 | /i{278 0 94 0 184 760 _sc 676 | 94 547 _m 677 | 184 547 _l 678 | 184 0 _l 679 | 94 0 _l 680 | 94 547 _l 681 | 94 760 _m 682 | 184 760 _l 683 | 184 646 _l 684 | 94 646 _l 685 | 94 760 _l 686 | _cl}_d 687 | /l{278 0 94 0 184 760 _sc 688 | 94 760 _m 689 | 184 760 _l 690 | 184 0 _l 691 | 94 0 _l 692 | 94 760 _l 693 | _cl}_d 694 | /m{{974 0 91 0 889 560 _sc 695 | 520 442 _m 696 | 542 482 569 511 600 531 _c 697 | 631 550 668 560 711 560 _c 698 | 767 560 811 540 842 500 _c 699 | 873 460 889 403 889 330 _c 700 | 889 0 _l 701 | 799 0 _l 702 | 799 327 _l 703 | 799 379 789 418 771 444 _c 704 | 752 469 724 482 686 482 _c 705 | 639 482 602 466 575 435 _c 706 | 548 404 535 362 535 309 _c 707 | 535 0 _l 708 | 445 0 _l 709 | 445 327 _l 710 | 445 379 435 418 417 444 _c 711 | 398 469 369 482 331 482 _c 712 | }_e{285 482 248 466 221 435 _c 713 | 194 404 181 362 181 309 _c 714 | 181 0 _l 715 | 91 0 _l 716 | 91 547 _l 717 | 181 547 _l 718 | 181 462 _l 719 | 201 495 226 520 255 536 _c 720 | 283 552 317 560 357 560 _c 721 | 397 560 430 550 458 530 _c 722 | 486 510 506 480 520 442 _c 723 | _cl}_e}_d 724 | /n{634 0 91 0 549 560 _sc 725 | 549 330 _m 726 | 549 0 _l 727 | 459 0 _l 728 | 459 327 _l 729 | 459 379 448 417 428 443 _c 730 | 408 469 378 482 338 482 _c 731 | 289 482 251 466 223 435 _c 732 | 195 404 181 362 181 309 _c 733 | 181 0 _l 734 | 91 0 _l 735 | 91 547 _l 736 | 181 547 _l 737 | 181 462 _l 738 | 202 494 227 519 257 535 _c 739 | 286 551 320 560 358 560 _c 740 | 420 560 468 540 500 501 _c 741 | 532 462 549 405 549 330 _c 742 | _cl}_d 743 | /o{612 0 55 -13 557 560 _sc 744 | 306 484 _m 745 | 258 484 220 465 192 427 _c 746 | 164 389 150 338 150 273 _c 747 | 150 207 163 156 191 118 _c 748 | 219 80 257 62 306 62 _c 749 | 354 62 392 80 420 118 _c 750 | 448 156 462 207 462 273 _c 751 | 462 337 448 389 420 427 _c 752 | 392 465 354 484 306 484 _c 753 | 306 560 _m 754 | 384 560 445 534 490 484 _c 755 | 534 433 557 363 557 273 _c 756 | 557 183 534 113 490 63 _c 757 | 445 12 384 -13 306 -13 _c 758 | 227 -13 165 12 121 63 _c 759 | 77 113 55 183 55 273 _c 760 | 55 363 77 433 121 484 _c 761 | 165 534 227 560 306 560 _c 762 | _cl}_d 763 | /p{{635 0 91 -207 580 560 _sc 764 | 181 82 _m 765 | 181 -207 _l 766 | 91 -207 _l 767 | 91 547 _l 768 | 181 547 _l 769 | 181 464 _l 770 | 199 496 223 520 252 536 _c 771 | 281 552 316 560 356 560 _c 772 | 422 560 476 533 518 481 _c 773 | 559 428 580 359 580 273 _c 774 | 580 187 559 117 518 65 _c 775 | 476 13 422 -13 356 -13 _c 776 | 316 -13 281 -5 252 10 _c 777 | 223 25 199 49 181 82 _c 778 | 487 273 _m 779 | 487 339 473 390 446 428 _c 780 | 418 466 381 485 334 485 _c 781 | }_e{286 485 249 466 222 428 _c 782 | 194 390 181 339 181 273 _c 783 | 181 207 194 155 222 117 _c 784 | 249 79 286 61 334 61 _c 785 | 381 61 418 79 446 117 _c 786 | 473 155 487 207 487 273 _c 787 | _cl}_e}_d 788 | /r{411 0 91 0 411 560 _sc 789 | 411 463 _m 790 | 401 469 390 473 378 476 _c 791 | 366 478 353 480 339 480 _c 792 | 288 480 249 463 222 430 _c 793 | 194 397 181 350 181 288 _c 794 | 181 0 _l 795 | 91 0 _l 796 | 91 547 _l 797 | 181 547 _l 798 | 181 462 _l 799 | 199 495 224 520 254 536 _c 800 | 284 552 321 560 365 560 _c 801 | 371 560 378 559 386 559 _c 802 | 393 558 401 557 411 555 _c 803 | 411 463 _l 804 | _cl}_d 805 | /s{{521 0 54 -13 472 560 _sc 806 | 443 531 _m 807 | 443 446 _l 808 | 417 458 391 468 364 475 _c 809 | 336 481 308 485 279 485 _c 810 | 234 485 200 478 178 464 _c 811 | 156 450 145 430 145 403 _c 812 | 145 382 153 366 169 354 _c 813 | 185 342 217 330 265 320 _c 814 | 296 313 _l 815 | 360 299 405 279 432 255 _c 816 | 458 230 472 195 472 151 _c 817 | 472 100 452 60 412 31 _c 818 | 372 1 316 -13 246 -13 _c 819 | 216 -13 186 -10 154 -5 _c 820 | }_e{122 0 89 8 54 20 _c 821 | 54 113 _l 822 | 87 95 120 82 152 74 _c 823 | 184 65 216 61 248 61 _c 824 | 290 61 323 68 346 82 _c 825 | 368 96 380 117 380 144 _c 826 | 380 168 371 187 355 200 _c 827 | 339 213 303 226 247 238 _c 828 | 216 245 _l 829 | 160 257 119 275 95 299 _c 830 | 70 323 58 356 58 399 _c 831 | 58 450 76 490 112 518 _c 832 | 148 546 200 560 268 560 _c 833 | 301 560 332 557 362 552 _c 834 | 391 547 418 540 443 531 _c 835 | }_e{_cl}_e}_d 836 | /t{392 0 27 0 368 702 _sc 837 | 183 702 _m 838 | 183 547 _l 839 | 368 547 _l 840 | 368 477 _l 841 | 183 477 _l 842 | 183 180 _l 843 | 183 135 189 106 201 94 _c 844 | 213 81 238 75 276 75 _c 845 | 368 75 _l 846 | 368 0 _l 847 | 276 0 _l 848 | 206 0 158 13 132 39 _c 849 | 106 65 93 112 93 180 _c 850 | 93 477 _l 851 | 27 477 _l 852 | 27 547 _l 853 | 93 547 _l 854 | 93 702 _l 855 | 183 702 _l 856 | _cl}_d 857 | /u{634 0 85 -13 543 547 _sc 858 | 85 216 _m 859 | 85 547 _l 860 | 175 547 _l 861 | 175 219 _l 862 | 175 167 185 129 205 103 _c 863 | 225 77 255 64 296 64 _c 864 | 344 64 383 79 411 110 _c 865 | 439 141 453 183 453 237 _c 866 | 453 547 _l 867 | 543 547 _l 868 | 543 0 _l 869 | 453 0 _l 870 | 453 84 _l 871 | 431 50 405 26 377 10 _c 872 | 348 -5 315 -13 277 -13 _c 873 | 214 -13 166 6 134 45 _c 874 | 101 83 85 140 85 216 _c 875 | _cl}_d 876 | /x{592 0 29 0 559 547 _sc 877 | 549 547 _m 878 | 351 281 _l 879 | 559 0 _l 880 | 453 0 _l 881 | 294 215 _l 882 | 135 0 _l 883 | 29 0 _l 884 | 241 286 _l 885 | 47 547 _l 886 | 153 547 _l 887 | 298 352 _l 888 | 443 547 _l 889 | 549 547 _l 890 | _cl}_d 891 | end readonly def 892 | 893 | /BuildGlyph 894 | {exch begin 895 | CharStrings exch 896 | 2 copy known not{pop /.notdef}if 897 | true 3 1 roll get exec 898 | end}_d 899 | 900 | /BuildChar { 901 | 1 index /Encoding get exch get 902 | 1 index /BuildGlyph get exec 903 | }_d 904 | 905 | FontName currentdict end definefont pop 906 | end 907 | %%EndProlog 908 | %%Page: 1 1 909 | mpldict begin 910 | 18 180 translate 911 | 576 432 0 0 clipbox 912 | 100000 setmiterlimit 913 | gsave 914 | 0 0 m 915 | 576 0 l 916 | 576 432 l 917 | 0 432 l 918 | cl 919 | 1.000 setgray 920 | fill 921 | grestore 922 | gsave 923 | 72 43.2 m 924 | 518.4 43.2 l 925 | 518.4 388.8 l 926 | 72 388.8 l 927 | cl 928 | 1.000 setgray 929 | fill 930 | grestore 931 | 1.000 setlinewidth 932 | 1 setlinejoin 933 | 0 setlinecap 934 | [] 0 setdash 935 | 0.000 0.500 0.000 setrgbcolor 936 | gsave 937 | 446.4 345.6 72 43.2 clipbox 938 | 114.431575 257.962853 m 939 | 114.431575 330.133147 l 940 | stroke 941 | grestore 942 | gsave 943 | 446.4 345.6 72 43.2 clipbox 944 | 128.374738 243.568137 m 945 | 128.374738 290.383863 l 946 | stroke 947 | grestore 948 | gsave 949 | 446.4 345.6 72 43.2 clipbox 950 | 134.083359 223.761067 m 951 | 134.083359 270.062933 l 952 | stroke 953 | grestore 954 | gsave 955 | 446.4 345.6 72 43.2 clipbox 956 | 148.026522 190.08 m 957 | 148.026522 236.16 l 958 | stroke 959 | grestore 960 | gsave 961 | 446.4 345.6 72 43.2 clipbox 962 | 155.497784 182.971939 m 963 | 155.497784 218.91149 l 964 | stroke 965 | grestore 966 | gsave 967 | 446.4 345.6 72 43.2 clipbox 968 | 164.907995 158.350948 m 969 | 164.907995 201.276346 l 970 | stroke 971 | grestore 972 | gsave 973 | 446.4 345.6 72 43.2 clipbox 974 | 175.149568 169.043881 m 975 | 175.149568 187.911548 l 976 | stroke 977 | grestore 978 | gsave 979 | 446.4 345.6 72 43.2 clipbox 980 | 185.500921 141.614547 m 981 | 185.500921 164.906069 l 982 | stroke 983 | grestore 984 | gsave 985 | 446.4 345.6 72 43.2 clipbox 986 | 195.564633 132.231042 m 987 | 195.564633 153.104958 l 988 | stroke 989 | grestore 990 | gsave 991 | 446.4 345.6 72 43.2 clipbox 992 | 205.152705 117.153232 m 993 | 205.152705 134.691692 l 994 | stroke 995 | grestore 996 | gsave 997 | 446.4 345.6 72 43.2 clipbox 998 | 215.216417 112.478131 m 999 | 215.216417 127.137869 l 1000 | stroke 1001 | grestore 1002 | gsave 1003 | 446.4 345.6 72 43.2 clipbox 1004 | 224.388459 105.594764 m 1005 | 224.388459 118.449374 l 1006 | stroke 1007 | grestore 1008 | gsave 1009 | 446.4 345.6 72 43.2 clipbox 1010 | 234.190327 100.408441 m 1011 | 234.190327 111.673136 l 1012 | stroke 1013 | grestore 1014 | gsave 1015 | 446.4 345.6 72 43.2 clipbox 1016 | 243.479922 90.139518 m 1017 | 243.479922 100.342343 l 1018 | stroke 1019 | grestore 1020 | gsave 1021 | 446.4 345.6 72 43.2 clipbox 1022 | 253.154621 86.641137 m 1023 | 253.154621 94.222863 l 1024 | stroke 1025 | grestore 1026 | gsave 1027 | 446.4 345.6 72 43.2 clipbox 1028 | 262.754528 81.374188 m 1029 | 262.754528 90.939812 l 1030 | stroke 1031 | grestore 1032 | gsave 1033 | 446.4 345.6 72 43.2 clipbox 1034 | 272.3426 80.032799 m 1035 | 272.3426 88.314278 l 1036 | stroke 1037 | grestore 1038 | gsave 1039 | 446.4 345.6 72 43.2 clipbox 1040 | 281.643032 74.35526 m 1041 | 281.643032 79.007025 l 1042 | stroke 1043 | grestore 1044 | gsave 1045 | 446.4 345.6 72 43.2 clipbox 1046 | 290.947535 72.465999 m 1047 | 290.947535 77.10787 l 1048 | stroke 1049 | grestore 1050 | gsave 1051 | 446.4 345.6 72 43.2 clipbox 1052 | 300.345294 69.964364 m 1053 | 300.345294 73.484499 l 1054 | stroke 1055 | grestore 1056 | gsave 1057 | 446.4 345.6 72 43.2 clipbox 1058 | 309.673392 67.383629 m 1059 | 309.673392 70.815351 l 1060 | stroke 1061 | grestore 1062 | gsave 1063 | 446.4 345.6 72 43.2 clipbox 1064 | 318.820631 64.310321 m 1065 | 318.820631 69.208461 l 1066 | stroke 1067 | grestore 1068 | gsave 1069 | 446.4 345.6 72 43.2 clipbox 1070 | 328.013201 62.542986 m 1071 | 328.013201 66.305404 l 1072 | stroke 1073 | grestore 1074 | gsave 1075 | 446.4 345.6 72 43.2 clipbox 1076 | 337.225988 60.969661 m 1077 | 337.225988 62.842265 l 1078 | stroke 1079 | grestore 1080 | gsave 1081 | 446.4 345.6 72 43.2 clipbox 1082 | 346.333383 58.272653 m 1083 | 346.333383 60.429876 l 1084 | stroke 1085 | grestore 1086 | gsave 1087 | 446.4 345.6 72 43.2 clipbox 1088 | 355.472826 57.010481 m 1089 | 355.472826 59.405297 l 1090 | stroke 1091 | grestore 1092 | gsave 1093 | 446.4 345.6 72 43.2 clipbox 1094 | 364.569631 55.471406 m 1095 | 364.569631 57.334284 l 1096 | stroke 1097 | grestore 1098 | gsave 1099 | 446.4 345.6 72 43.2 clipbox 1100 | 373.629699 54.475257 m 1101 | 373.629699 57.615896 l 1102 | stroke 1103 | grestore 1104 | gsave 1105 | 446.4 345.6 72 43.2 clipbox 1106 | 382.715515 54.025999 m 1107 | 382.715515 56.77277 l 1108 | stroke 1109 | grestore 1110 | gsave 1111 | 446.4 345.6 72 43.2 clipbox 1112 | 391.732377 52.370837 m 1113 | 391.732377 53.299381 l 1114 | stroke 1115 | grestore 1116 | gsave 1117 | 446.4 345.6 72 43.2 clipbox 1118 | 400.758235 51.633463 m 1119 | 400.758235 53.357218 l 1120 | stroke 1121 | grestore 1122 | gsave 1123 | 446.4 345.6 72 43.2 clipbox 1124 | 409.751993 51.233889 m 1125 | 409.751993 52.892256 l 1126 | stroke 1127 | grestore 1128 | [6 6] 0 setdash 1129 | gsave 1130 | 446.4 345.6 72 43.2 clipbox 1131 | 114.431575 294.048 m 1132 | 128.374738 266.976 l 1133 | 134.083359 246.912 l 1134 | 148.026522 213.12 l 1135 | 155.497784 200.941714 l 1136 | 164.907995 179.813647 l 1137 | 175.149568 178.477714 l 1138 | 185.500921 153.260308 l 1139 | 195.564633 142.668 l 1140 | 205.152705 125.922462 l 1141 | 215.216417 119.808 l 1142 | 224.388459 112.022069 l 1143 | 234.190327 106.040789 l 1144 | 243.479922 95.24093 l 1145 | 253.154621 90.432 l 1146 | 262.754528 86.157 l 1147 | 272.3426 84.173538 l 1148 | 281.643032 76.681143 l 1149 | 290.947535 74.786934 l 1150 | 300.345294 71.724432 l 1151 | 309.673392 69.09949 l 1152 | 318.820631 66.759391 l 1153 | 328.013201 64.424195 l 1154 | 337.225988 61.905963 l 1155 | 346.333383 59.351265 l 1156 | 355.472826 58.207889 l 1157 | 364.569631 56.402845 l 1158 | 373.629699 56.045577 l 1159 | 382.715515 55.399385 l 1160 | 391.732377 52.835109 l 1161 | 400.758235 52.49534 l 1162 | 409.751993 52.063073 l 1163 | stroke 1164 | grestore 1165 | 0.500 setlinewidth 1166 | [] 0 setdash 1167 | gsave 1168 | 446.4 345.6 72 43.2 clipbox 1169 | /o { 1170 | gsave 1171 | newpath 1172 | translate 1173 | 0.5 setlinewidth 1174 | 1 setlinejoin 1175 | 0 setlinecap 1176 | 3 -0 m 1177 | -3 0 l 1178 | 1179 | gsave 1180 | 0.000 0.500 0.000 setrgbcolor 1181 | fill 1182 | grestore 1183 | stroke 1184 | grestore 1185 | } bind def 1186 | 114.432 257.963 o 1187 | 128.375 243.568 o 1188 | 134.083 223.761 o 1189 | 148.027 190.08 o 1190 | 155.498 182.972 o 1191 | 164.908 158.351 o 1192 | 175.15 169.044 o 1193 | 185.501 141.615 o 1194 | 195.565 132.231 o 1195 | 205.153 117.153 o 1196 | 215.216 112.478 o 1197 | 224.388 105.595 o 1198 | 234.19 100.408 o 1199 | 243.48 90.1395 o 1200 | 253.155 86.6411 o 1201 | 262.755 81.3742 o 1202 | 272.343 80.0328 o 1203 | 281.643 74.3553 o 1204 | 290.948 72.466 o 1205 | 300.345 69.9644 o 1206 | 309.673 67.3836 o 1207 | 318.821 64.3103 o 1208 | 328.013 62.543 o 1209 | 337.226 60.9697 o 1210 | 346.333 58.2727 o 1211 | 355.473 57.0105 o 1212 | 364.57 55.4714 o 1213 | 373.63 54.4753 o 1214 | 382.716 54.026 o 1215 | 391.732 52.3708 o 1216 | 400.758 51.6335 o 1217 | 409.752 51.2339 o 1218 | grestore 1219 | gsave 1220 | 446.4 345.6 72 43.2 clipbox 1221 | /o { 1222 | gsave 1223 | newpath 1224 | translate 1225 | 0.5 setlinewidth 1226 | 1 setlinejoin 1227 | 0 setlinecap 1228 | 3 -0 m 1229 | -3 0 l 1230 | 1231 | gsave 1232 | 0.000 0.500 0.000 setrgbcolor 1233 | fill 1234 | grestore 1235 | stroke 1236 | grestore 1237 | } bind def 1238 | 114.432 330.133 o 1239 | 128.375 290.384 o 1240 | 134.083 270.063 o 1241 | 148.027 236.16 o 1242 | 155.498 218.911 o 1243 | 164.908 201.276 o 1244 | 175.15 187.912 o 1245 | 185.501 164.906 o 1246 | 195.565 153.105 o 1247 | 205.153 134.692 o 1248 | 215.216 127.138 o 1249 | 224.388 118.449 o 1250 | 234.19 111.673 o 1251 | 243.48 100.342 o 1252 | 253.155 94.2229 o 1253 | 262.755 90.9398 o 1254 | 272.343 88.3143 o 1255 | 281.643 79.007 o 1256 | 290.948 77.1079 o 1257 | 300.345 73.4845 o 1258 | 309.673 70.8154 o 1259 | 318.821 69.2085 o 1260 | 328.013 66.3054 o 1261 | 337.226 62.8423 o 1262 | 346.333 60.4299 o 1263 | 355.473 59.4053 o 1264 | 364.57 57.3343 o 1265 | 373.63 57.6159 o 1266 | 382.716 56.7728 o 1267 | 391.732 53.2994 o 1268 | 400.758 53.3572 o 1269 | 409.752 52.8923 o 1270 | grestore 1271 | 1.000 setlinewidth 1272 | [6 6] 0 setdash 1273 | gsave 1274 | 446.4 345.6 72 43.2 clipbox 1275 | 114.431575 294.048 m 1276 | 128.374738 266.976 l 1277 | 134.083359 246.912 l 1278 | 148.026522 213.12 l 1279 | 155.497784 200.941714 l 1280 | 164.907995 179.813647 l 1281 | 175.149568 178.477714 l 1282 | 185.500921 153.260308 l 1283 | 195.564633 142.668 l 1284 | 205.152705 125.922462 l 1285 | 215.216417 119.808 l 1286 | 224.388459 112.022069 l 1287 | 234.190327 106.040789 l 1288 | 243.479922 95.24093 l 1289 | 253.154621 90.432 l 1290 | 262.754528 86.157 l 1291 | 272.3426 84.173538 l 1292 | 281.643032 76.681143 l 1293 | 290.947535 74.786934 l 1294 | 300.345294 71.724432 l 1295 | 309.673392 69.09949 l 1296 | 318.820631 66.759391 l 1297 | 328.013201 64.424195 l 1298 | 337.225988 61.905963 l 1299 | 346.333383 59.351265 l 1300 | 355.472826 58.207889 l 1301 | 364.569631 56.402845 l 1302 | 373.629699 56.045577 l 1303 | 382.715515 55.399385 l 1304 | 391.732377 52.835109 l 1305 | 400.758235 52.49534 l 1306 | 409.751993 52.063073 l 1307 | stroke 1308 | grestore 1309 | 2 setlinecap 1310 | [] 0 setdash 1311 | 0.000 0.000 1.000 setrgbcolor 1312 | gsave 1313 | 446.4 345.6 72 43.2 clipbox 1314 | 114.431575 283.066628 m 1315 | 128.374738 247.636963 l 1316 | 134.083359 234.687907 l 1317 | 148.026522 206.404054 l 1318 | 155.497784 193.00913 l 1319 | 164.907995 177.691038 l 1320 | 175.149568 162.794114 l 1321 | 185.500921 149.413514 l 1322 | 195.564633 137.841507 l 1323 | 205.152705 127.991301 l 1324 | 215.216417 118.753253 l 1325 | 224.388459 111.213302 l 1326 | 234.190327 103.985392 l 1327 | 243.479922 97.84554 l 1328 | 253.154621 92.10949 l 1329 | 262.754528 87.013089 l 1330 | 272.3426 82.453061 l 1331 | 281.643032 78.483778 l 1332 | 290.947535 74.91439 l 1333 | 300.345294 71.675635 l 1334 | 309.673392 68.788053 l 1335 | 318.820631 66.241004 l 1336 | 328.013201 63.936713 l 1337 | 337.225988 61.858545 l 1338 | 346.333383 60.008938 l 1339 | 355.472826 58.33712 l 1340 | 364.569631 56.838245 l 1341 | 373.629699 55.492963 l 1342 | 382.715515 54.277111 l 1343 | 391.732377 53.189407 l 1344 | 400.758235 52.20758 l 1345 | 409.751993 51.325242 l 1346 | stroke 1347 | grestore 1348 | 0.500 setlinewidth 1349 | 0 setlinejoin 1350 | 0 setlinecap 1351 | 0.000 setgray 1352 | gsave 1353 | 446.4 345.6 72 43.2 clipbox 1354 | /o { 1355 | gsave 1356 | newpath 1357 | translate 1358 | 0.5 setlinewidth 1359 | 0 setlinejoin 1360 | 0 setlinecap 1361 | 0 3 m 1362 | -3 -3 l 1363 | 3 -3 l 1364 | cl 1365 | 1366 | gsave 1367 | 0.000 0.000 1.000 setrgbcolor 1368 | fill 1369 | grestore 1370 | stroke 1371 | grestore 1372 | } bind def 1373 | 114.432 283.067 o 1374 | 128.375 247.637 o 1375 | 134.083 234.688 o 1376 | 148.027 206.404 o 1377 | 155.498 193.009 o 1378 | 164.908 177.691 o 1379 | 175.15 162.794 o 1380 | 185.501 149.414 o 1381 | 195.565 137.842 o 1382 | 205.153 127.991 o 1383 | 215.216 118.753 o 1384 | 224.388 111.213 o 1385 | 234.19 103.985 o 1386 | 243.48 97.8455 o 1387 | 253.155 92.1095 o 1388 | 262.755 87.0131 o 1389 | 272.343 82.4531 o 1390 | 281.643 78.4838 o 1391 | 290.948 74.9144 o 1392 | 300.345 71.6756 o 1393 | 309.673 68.7881 o 1394 | 318.821 66.241 o 1395 | 328.013 63.9367 o 1396 | 337.226 61.8585 o 1397 | 346.333 60.0089 o 1398 | 355.473 58.3371 o 1399 | 364.57 56.8382 o 1400 | 373.63 55.493 o 1401 | 382.716 54.2771 o 1402 | 391.732 53.1894 o 1403 | 400.758 52.2076 o 1404 | 409.752 51.3252 o 1405 | grestore 1406 | 1.000 setlinewidth 1407 | 2 setlinecap 1408 | gsave 1409 | 518.4 43.2 m 1410 | 518.4 388.8 l 1411 | stroke 1412 | grestore 1413 | gsave 1414 | 72 43.2 m 1415 | 72 388.8 l 1416 | stroke 1417 | grestore 1418 | gsave 1419 | 72 388.8 m 1420 | 518.4 388.8 l 1421 | stroke 1422 | grestore 1423 | gsave 1424 | 72 43.2 m 1425 | 518.4 43.2 l 1426 | stroke 1427 | grestore 1428 | 0.500 setlinewidth 1429 | 1 setlinejoin 1430 | 0 setlinecap 1431 | gsave 1432 | /o { 1433 | gsave 1434 | newpath 1435 | translate 1436 | 0.5 setlinewidth 1437 | 1 setlinejoin 1438 | 0 setlinecap 1439 | 0 0 m 1440 | 0 4 l 1441 | 1442 | gsave 1443 | 0.000 setgray 1444 | fill 1445 | grestore 1446 | stroke 1447 | grestore 1448 | } bind def 1449 | 72 43.2 o 1450 | grestore 1451 | gsave 1452 | /o { 1453 | gsave 1454 | newpath 1455 | translate 1456 | 0.5 setlinewidth 1457 | 1 setlinejoin 1458 | 0 setlinecap 1459 | 0 0 m 1460 | 0 -4 l 1461 | 1462 | gsave 1463 | 0.000 setgray 1464 | fill 1465 | grestore 1466 | stroke 1467 | grestore 1468 | } bind def 1469 | 72 388.8 o 1470 | grestore 1471 | gsave 1472 | 55.000000 23.950000 translate 1473 | 0.000000 rotate 1474 | /BitstreamVeraSans-Roman findfont 1475 | 18.0 scalefont 1476 | setfont 1477 | 0.000000 0.307500 moveto 1478 | /one glyphshow 1479 | 1480 | 11.452148 0.307500 moveto 1481 | /zero glyphshow 1482 | 1483 | /BitstreamVeraSans-Roman findfont 1484 | 12.6 scalefont 1485 | setfont 1486 | 23.896547 8.812500 moveto 1487 | /one glyphshow 1488 | 1489 | 1490 | grestore 1491 | gsave 1492 | /o { 1493 | gsave 1494 | newpath 1495 | translate 1496 | 0.5 setlinewidth 1497 | 1 setlinejoin 1498 | 0 setlinecap 1499 | 0 0 m 1500 | 0 4 l 1501 | 1502 | gsave 1503 | 0.000 setgray 1504 | fill 1505 | grestore 1506 | stroke 1507 | grestore 1508 | } bind def 1509 | 183.6 43.2 o 1510 | grestore 1511 | gsave 1512 | /o { 1513 | gsave 1514 | newpath 1515 | translate 1516 | 0.5 setlinewidth 1517 | 1 setlinejoin 1518 | 0 setlinecap 1519 | 0 0 m 1520 | 0 -4 l 1521 | 1522 | gsave 1523 | 0.000 setgray 1524 | fill 1525 | grestore 1526 | stroke 1527 | grestore 1528 | } bind def 1529 | 183.6 388.8 o 1530 | grestore 1531 | gsave 1532 | 166.600000 23.950000 translate 1533 | 0.000000 rotate 1534 | /BitstreamVeraSans-Roman findfont 1535 | 18.0 scalefont 1536 | setfont 1537 | 0.000000 0.143438 moveto 1538 | /one glyphshow 1539 | 1540 | 11.452148 0.143438 moveto 1541 | /zero glyphshow 1542 | 1543 | /BitstreamVeraSans-Roman findfont 1544 | 12.6 scalefont 1545 | setfont 1546 | 23.896547 8.648438 moveto 1547 | /two glyphshow 1548 | 1549 | 1550 | grestore 1551 | gsave 1552 | /o { 1553 | gsave 1554 | newpath 1555 | translate 1556 | 0.5 setlinewidth 1557 | 1 setlinejoin 1558 | 0 setlinecap 1559 | 0 0 m 1560 | 0 4 l 1561 | 1562 | gsave 1563 | 0.000 setgray 1564 | fill 1565 | grestore 1566 | stroke 1567 | grestore 1568 | } bind def 1569 | 295.2 43.2 o 1570 | grestore 1571 | gsave 1572 | /o { 1573 | gsave 1574 | newpath 1575 | translate 1576 | 0.5 setlinewidth 1577 | 1 setlinejoin 1578 | 0 setlinecap 1579 | 0 0 m 1580 | 0 -4 l 1581 | 1582 | gsave 1583 | 0.000 setgray 1584 | fill 1585 | grestore 1586 | stroke 1587 | grestore 1588 | } bind def 1589 | 295.2 388.8 o 1590 | grestore 1591 | gsave 1592 | 278.200000 23.950000 translate 1593 | 0.000000 rotate 1594 | /BitstreamVeraSans-Roman findfont 1595 | 18.0 scalefont 1596 | setfont 1597 | 0.000000 0.143438 moveto 1598 | /one glyphshow 1599 | 1600 | 11.452148 0.143438 moveto 1601 | /zero glyphshow 1602 | 1603 | /BitstreamVeraSans-Roman findfont 1604 | 12.6 scalefont 1605 | setfont 1606 | 23.896547 8.648438 moveto 1607 | /three glyphshow 1608 | 1609 | 1610 | grestore 1611 | gsave 1612 | /o { 1613 | gsave 1614 | newpath 1615 | translate 1616 | 0.5 setlinewidth 1617 | 1 setlinejoin 1618 | 0 setlinecap 1619 | 0 0 m 1620 | 0 4 l 1621 | 1622 | gsave 1623 | 0.000 setgray 1624 | fill 1625 | grestore 1626 | stroke 1627 | grestore 1628 | } bind def 1629 | 406.8 43.2 o 1630 | grestore 1631 | gsave 1632 | /o { 1633 | gsave 1634 | newpath 1635 | translate 1636 | 0.5 setlinewidth 1637 | 1 setlinejoin 1638 | 0 setlinecap 1639 | 0 0 m 1640 | 0 -4 l 1641 | 1642 | gsave 1643 | 0.000 setgray 1644 | fill 1645 | grestore 1646 | stroke 1647 | grestore 1648 | } bind def 1649 | 406.8 388.8 o 1650 | grestore 1651 | gsave 1652 | 389.800000 23.950000 translate 1653 | 0.000000 rotate 1654 | /BitstreamVeraSans-Roman findfont 1655 | 18.0 scalefont 1656 | setfont 1657 | 0.000000 0.307500 moveto 1658 | /one glyphshow 1659 | 1660 | 11.452148 0.307500 moveto 1661 | /zero glyphshow 1662 | 1663 | /BitstreamVeraSans-Roman findfont 1664 | 12.6 scalefont 1665 | setfont 1666 | 23.896547 8.812500 moveto 1667 | /four glyphshow 1668 | 1669 | 1670 | grestore 1671 | gsave 1672 | /o { 1673 | gsave 1674 | newpath 1675 | translate 1676 | 0.5 setlinewidth 1677 | 1 setlinejoin 1678 | 0 setlinecap 1679 | 0 0 m 1680 | 0 4 l 1681 | 1682 | gsave 1683 | 0.000 setgray 1684 | fill 1685 | grestore 1686 | stroke 1687 | grestore 1688 | } bind def 1689 | 518.4 43.2 o 1690 | grestore 1691 | gsave 1692 | /o { 1693 | gsave 1694 | newpath 1695 | translate 1696 | 0.5 setlinewidth 1697 | 1 setlinejoin 1698 | 0 setlinecap 1699 | 0 0 m 1700 | 0 -4 l 1701 | 1702 | gsave 1703 | 0.000 setgray 1704 | fill 1705 | grestore 1706 | stroke 1707 | grestore 1708 | } bind def 1709 | 518.4 388.8 o 1710 | grestore 1711 | gsave 1712 | 501.400000 23.950000 translate 1713 | 0.000000 rotate 1714 | /BitstreamVeraSans-Roman findfont 1715 | 18.0 scalefont 1716 | setfont 1717 | 0.000000 0.307500 moveto 1718 | /one glyphshow 1719 | 1720 | 11.452148 0.307500 moveto 1721 | /zero glyphshow 1722 | 1723 | /BitstreamVeraSans-Roman findfont 1724 | 12.6 scalefont 1725 | setfont 1726 | 23.896547 8.812500 moveto 1727 | /five glyphshow 1728 | 1729 | 1730 | grestore 1731 | gsave 1732 | /o { 1733 | gsave 1734 | newpath 1735 | translate 1736 | 0.5 setlinewidth 1737 | 1 setlinejoin 1738 | 0 setlinecap 1739 | 0 0 m 1740 | 0 2 l 1741 | 1742 | gsave 1743 | 0.000 setgray 1744 | fill 1745 | grestore 1746 | stroke 1747 | grestore 1748 | } bind def 1749 | 105.595 43.2 o 1750 | grestore 1751 | gsave 1752 | /o { 1753 | gsave 1754 | newpath 1755 | translate 1756 | 0.5 setlinewidth 1757 | 1 setlinejoin 1758 | 0 setlinecap 1759 | 0 0 m 1760 | 0 -2 l 1761 | 1762 | gsave 1763 | 0.000 setgray 1764 | fill 1765 | grestore 1766 | stroke 1767 | grestore 1768 | } bind def 1769 | 105.595 388.8 o 1770 | grestore 1771 | gsave 1772 | /o { 1773 | gsave 1774 | newpath 1775 | translate 1776 | 0.5 setlinewidth 1777 | 1 setlinejoin 1778 | 0 setlinecap 1779 | 0 0 m 1780 | 0 2 l 1781 | 1782 | gsave 1783 | 0.000 setgray 1784 | fill 1785 | grestore 1786 | stroke 1787 | grestore 1788 | } bind def 1789 | 125.247 43.2 o 1790 | grestore 1791 | gsave 1792 | /o { 1793 | gsave 1794 | newpath 1795 | translate 1796 | 0.5 setlinewidth 1797 | 1 setlinejoin 1798 | 0 setlinecap 1799 | 0 0 m 1800 | 0 -2 l 1801 | 1802 | gsave 1803 | 0.000 setgray 1804 | fill 1805 | grestore 1806 | stroke 1807 | grestore 1808 | } bind def 1809 | 125.247 388.8 o 1810 | grestore 1811 | gsave 1812 | /o { 1813 | gsave 1814 | newpath 1815 | translate 1816 | 0.5 setlinewidth 1817 | 1 setlinejoin 1818 | 0 setlinecap 1819 | 0 0 m 1820 | 0 2 l 1821 | 1822 | gsave 1823 | 0.000 setgray 1824 | fill 1825 | grestore 1826 | stroke 1827 | grestore 1828 | } bind def 1829 | 139.19 43.2 o 1830 | grestore 1831 | gsave 1832 | /o { 1833 | gsave 1834 | newpath 1835 | translate 1836 | 0.5 setlinewidth 1837 | 1 setlinejoin 1838 | 0 setlinecap 1839 | 0 0 m 1840 | 0 -2 l 1841 | 1842 | gsave 1843 | 0.000 setgray 1844 | fill 1845 | grestore 1846 | stroke 1847 | grestore 1848 | } bind def 1849 | 139.19 388.8 o 1850 | grestore 1851 | gsave 1852 | /o { 1853 | gsave 1854 | newpath 1855 | translate 1856 | 0.5 setlinewidth 1857 | 1 setlinejoin 1858 | 0 setlinecap 1859 | 0 0 m 1860 | 0 2 l 1861 | 1862 | gsave 1863 | 0.000 setgray 1864 | fill 1865 | grestore 1866 | stroke 1867 | grestore 1868 | } bind def 1869 | 150.005 43.2 o 1870 | grestore 1871 | gsave 1872 | /o { 1873 | gsave 1874 | newpath 1875 | translate 1876 | 0.5 setlinewidth 1877 | 1 setlinejoin 1878 | 0 setlinecap 1879 | 0 0 m 1880 | 0 -2 l 1881 | 1882 | gsave 1883 | 0.000 setgray 1884 | fill 1885 | grestore 1886 | stroke 1887 | grestore 1888 | } bind def 1889 | 150.005 388.8 o 1890 | grestore 1891 | gsave 1892 | /o { 1893 | gsave 1894 | newpath 1895 | translate 1896 | 0.5 setlinewidth 1897 | 1 setlinejoin 1898 | 0 setlinecap 1899 | 0 0 m 1900 | 0 2 l 1901 | 1902 | gsave 1903 | 0.000 setgray 1904 | fill 1905 | grestore 1906 | stroke 1907 | grestore 1908 | } bind def 1909 | 158.842 43.2 o 1910 | grestore 1911 | gsave 1912 | /o { 1913 | gsave 1914 | newpath 1915 | translate 1916 | 0.5 setlinewidth 1917 | 1 setlinejoin 1918 | 0 setlinecap 1919 | 0 0 m 1920 | 0 -2 l 1921 | 1922 | gsave 1923 | 0.000 setgray 1924 | fill 1925 | grestore 1926 | stroke 1927 | grestore 1928 | } bind def 1929 | 158.842 388.8 o 1930 | grestore 1931 | gsave 1932 | /o { 1933 | gsave 1934 | newpath 1935 | translate 1936 | 0.5 setlinewidth 1937 | 1 setlinejoin 1938 | 0 setlinecap 1939 | 0 0 m 1940 | 0 2 l 1941 | 1942 | gsave 1943 | 0.000 setgray 1944 | fill 1945 | grestore 1946 | stroke 1947 | grestore 1948 | } bind def 1949 | 166.313 43.2 o 1950 | grestore 1951 | gsave 1952 | /o { 1953 | gsave 1954 | newpath 1955 | translate 1956 | 0.5 setlinewidth 1957 | 1 setlinejoin 1958 | 0 setlinecap 1959 | 0 0 m 1960 | 0 -2 l 1961 | 1962 | gsave 1963 | 0.000 setgray 1964 | fill 1965 | grestore 1966 | stroke 1967 | grestore 1968 | } bind def 1969 | 166.313 388.8 o 1970 | grestore 1971 | gsave 1972 | /o { 1973 | gsave 1974 | newpath 1975 | translate 1976 | 0.5 setlinewidth 1977 | 1 setlinejoin 1978 | 0 setlinecap 1979 | 0 0 m 1980 | 0 2 l 1981 | 1982 | gsave 1983 | 0.000 setgray 1984 | fill 1985 | grestore 1986 | stroke 1987 | grestore 1988 | } bind def 1989 | 172.785 43.2 o 1990 | grestore 1991 | gsave 1992 | /o { 1993 | gsave 1994 | newpath 1995 | translate 1996 | 0.5 setlinewidth 1997 | 1 setlinejoin 1998 | 0 setlinecap 1999 | 0 0 m 2000 | 0 -2 l 2001 | 2002 | gsave 2003 | 0.000 setgray 2004 | fill 2005 | grestore 2006 | stroke 2007 | grestore 2008 | } bind def 2009 | 172.785 388.8 o 2010 | grestore 2011 | gsave 2012 | /o { 2013 | gsave 2014 | newpath 2015 | translate 2016 | 0.5 setlinewidth 2017 | 1 setlinejoin 2018 | 0 setlinecap 2019 | 0 0 m 2020 | 0 2 l 2021 | 2022 | gsave 2023 | 0.000 setgray 2024 | fill 2025 | grestore 2026 | stroke 2027 | grestore 2028 | } bind def 2029 | 178.493 43.2 o 2030 | grestore 2031 | gsave 2032 | /o { 2033 | gsave 2034 | newpath 2035 | translate 2036 | 0.5 setlinewidth 2037 | 1 setlinejoin 2038 | 0 setlinecap 2039 | 0 0 m 2040 | 0 -2 l 2041 | 2042 | gsave 2043 | 0.000 setgray 2044 | fill 2045 | grestore 2046 | stroke 2047 | grestore 2048 | } bind def 2049 | 178.493 388.8 o 2050 | grestore 2051 | gsave 2052 | /o { 2053 | gsave 2054 | newpath 2055 | translate 2056 | 0.5 setlinewidth 2057 | 1 setlinejoin 2058 | 0 setlinecap 2059 | 0 0 m 2060 | 0 2 l 2061 | 2062 | gsave 2063 | 0.000 setgray 2064 | fill 2065 | grestore 2066 | stroke 2067 | grestore 2068 | } bind def 2069 | 217.195 43.2 o 2070 | grestore 2071 | gsave 2072 | /o { 2073 | gsave 2074 | newpath 2075 | translate 2076 | 0.5 setlinewidth 2077 | 1 setlinejoin 2078 | 0 setlinecap 2079 | 0 0 m 2080 | 0 -2 l 2081 | 2082 | gsave 2083 | 0.000 setgray 2084 | fill 2085 | grestore 2086 | stroke 2087 | grestore 2088 | } bind def 2089 | 217.195 388.8 o 2090 | grestore 2091 | gsave 2092 | /o { 2093 | gsave 2094 | newpath 2095 | translate 2096 | 0.5 setlinewidth 2097 | 1 setlinejoin 2098 | 0 setlinecap 2099 | 0 0 m 2100 | 0 2 l 2101 | 2102 | gsave 2103 | 0.000 setgray 2104 | fill 2105 | grestore 2106 | stroke 2107 | grestore 2108 | } bind def 2109 | 236.847 43.2 o 2110 | grestore 2111 | gsave 2112 | /o { 2113 | gsave 2114 | newpath 2115 | translate 2116 | 0.5 setlinewidth 2117 | 1 setlinejoin 2118 | 0 setlinecap 2119 | 0 0 m 2120 | 0 -2 l 2121 | 2122 | gsave 2123 | 0.000 setgray 2124 | fill 2125 | grestore 2126 | stroke 2127 | grestore 2128 | } bind def 2129 | 236.847 388.8 o 2130 | grestore 2131 | gsave 2132 | /o { 2133 | gsave 2134 | newpath 2135 | translate 2136 | 0.5 setlinewidth 2137 | 1 setlinejoin 2138 | 0 setlinecap 2139 | 0 0 m 2140 | 0 2 l 2141 | 2142 | gsave 2143 | 0.000 setgray 2144 | fill 2145 | grestore 2146 | stroke 2147 | grestore 2148 | } bind def 2149 | 250.79 43.2 o 2150 | grestore 2151 | gsave 2152 | /o { 2153 | gsave 2154 | newpath 2155 | translate 2156 | 0.5 setlinewidth 2157 | 1 setlinejoin 2158 | 0 setlinecap 2159 | 0 0 m 2160 | 0 -2 l 2161 | 2162 | gsave 2163 | 0.000 setgray 2164 | fill 2165 | grestore 2166 | stroke 2167 | grestore 2168 | } bind def 2169 | 250.79 388.8 o 2170 | grestore 2171 | gsave 2172 | /o { 2173 | gsave 2174 | newpath 2175 | translate 2176 | 0.5 setlinewidth 2177 | 1 setlinejoin 2178 | 0 setlinecap 2179 | 0 0 m 2180 | 0 2 l 2181 | 2182 | gsave 2183 | 0.000 setgray 2184 | fill 2185 | grestore 2186 | stroke 2187 | grestore 2188 | } bind def 2189 | 261.605 43.2 o 2190 | grestore 2191 | gsave 2192 | /o { 2193 | gsave 2194 | newpath 2195 | translate 2196 | 0.5 setlinewidth 2197 | 1 setlinejoin 2198 | 0 setlinecap 2199 | 0 0 m 2200 | 0 -2 l 2201 | 2202 | gsave 2203 | 0.000 setgray 2204 | fill 2205 | grestore 2206 | stroke 2207 | grestore 2208 | } bind def 2209 | 261.605 388.8 o 2210 | grestore 2211 | gsave 2212 | /o { 2213 | gsave 2214 | newpath 2215 | translate 2216 | 0.5 setlinewidth 2217 | 1 setlinejoin 2218 | 0 setlinecap 2219 | 0 0 m 2220 | 0 2 l 2221 | 2222 | gsave 2223 | 0.000 setgray 2224 | fill 2225 | grestore 2226 | stroke 2227 | grestore 2228 | } bind def 2229 | 270.442 43.2 o 2230 | grestore 2231 | gsave 2232 | /o { 2233 | gsave 2234 | newpath 2235 | translate 2236 | 0.5 setlinewidth 2237 | 1 setlinejoin 2238 | 0 setlinecap 2239 | 0 0 m 2240 | 0 -2 l 2241 | 2242 | gsave 2243 | 0.000 setgray 2244 | fill 2245 | grestore 2246 | stroke 2247 | grestore 2248 | } bind def 2249 | 270.442 388.8 o 2250 | grestore 2251 | gsave 2252 | /o { 2253 | gsave 2254 | newpath 2255 | translate 2256 | 0.5 setlinewidth 2257 | 1 setlinejoin 2258 | 0 setlinecap 2259 | 0 0 m 2260 | 0 2 l 2261 | 2262 | gsave 2263 | 0.000 setgray 2264 | fill 2265 | grestore 2266 | stroke 2267 | grestore 2268 | } bind def 2269 | 277.913 43.2 o 2270 | grestore 2271 | gsave 2272 | /o { 2273 | gsave 2274 | newpath 2275 | translate 2276 | 0.5 setlinewidth 2277 | 1 setlinejoin 2278 | 0 setlinecap 2279 | 0 0 m 2280 | 0 -2 l 2281 | 2282 | gsave 2283 | 0.000 setgray 2284 | fill 2285 | grestore 2286 | stroke 2287 | grestore 2288 | } bind def 2289 | 277.913 388.8 o 2290 | grestore 2291 | gsave 2292 | /o { 2293 | gsave 2294 | newpath 2295 | translate 2296 | 0.5 setlinewidth 2297 | 1 setlinejoin 2298 | 0 setlinecap 2299 | 0 0 m 2300 | 0 2 l 2301 | 2302 | gsave 2303 | 0.000 setgray 2304 | fill 2305 | grestore 2306 | stroke 2307 | grestore 2308 | } bind def 2309 | 284.385 43.2 o 2310 | grestore 2311 | gsave 2312 | /o { 2313 | gsave 2314 | newpath 2315 | translate 2316 | 0.5 setlinewidth 2317 | 1 setlinejoin 2318 | 0 setlinecap 2319 | 0 0 m 2320 | 0 -2 l 2321 | 2322 | gsave 2323 | 0.000 setgray 2324 | fill 2325 | grestore 2326 | stroke 2327 | grestore 2328 | } bind def 2329 | 284.385 388.8 o 2330 | grestore 2331 | gsave 2332 | /o { 2333 | gsave 2334 | newpath 2335 | translate 2336 | 0.5 setlinewidth 2337 | 1 setlinejoin 2338 | 0 setlinecap 2339 | 0 0 m 2340 | 0 2 l 2341 | 2342 | gsave 2343 | 0.000 setgray 2344 | fill 2345 | grestore 2346 | stroke 2347 | grestore 2348 | } bind def 2349 | 290.093 43.2 o 2350 | grestore 2351 | gsave 2352 | /o { 2353 | gsave 2354 | newpath 2355 | translate 2356 | 0.5 setlinewidth 2357 | 1 setlinejoin 2358 | 0 setlinecap 2359 | 0 0 m 2360 | 0 -2 l 2361 | 2362 | gsave 2363 | 0.000 setgray 2364 | fill 2365 | grestore 2366 | stroke 2367 | grestore 2368 | } bind def 2369 | 290.093 388.8 o 2370 | grestore 2371 | gsave 2372 | /o { 2373 | gsave 2374 | newpath 2375 | translate 2376 | 0.5 setlinewidth 2377 | 1 setlinejoin 2378 | 0 setlinecap 2379 | 0 0 m 2380 | 0 2 l 2381 | 2382 | gsave 2383 | 0.000 setgray 2384 | fill 2385 | grestore 2386 | stroke 2387 | grestore 2388 | } bind def 2389 | 328.795 43.2 o 2390 | grestore 2391 | gsave 2392 | /o { 2393 | gsave 2394 | newpath 2395 | translate 2396 | 0.5 setlinewidth 2397 | 1 setlinejoin 2398 | 0 setlinecap 2399 | 0 0 m 2400 | 0 -2 l 2401 | 2402 | gsave 2403 | 0.000 setgray 2404 | fill 2405 | grestore 2406 | stroke 2407 | grestore 2408 | } bind def 2409 | 328.795 388.8 o 2410 | grestore 2411 | gsave 2412 | /o { 2413 | gsave 2414 | newpath 2415 | translate 2416 | 0.5 setlinewidth 2417 | 1 setlinejoin 2418 | 0 setlinecap 2419 | 0 0 m 2420 | 0 2 l 2421 | 2422 | gsave 2423 | 0.000 setgray 2424 | fill 2425 | grestore 2426 | stroke 2427 | grestore 2428 | } bind def 2429 | 348.447 43.2 o 2430 | grestore 2431 | gsave 2432 | /o { 2433 | gsave 2434 | newpath 2435 | translate 2436 | 0.5 setlinewidth 2437 | 1 setlinejoin 2438 | 0 setlinecap 2439 | 0 0 m 2440 | 0 -2 l 2441 | 2442 | gsave 2443 | 0.000 setgray 2444 | fill 2445 | grestore 2446 | stroke 2447 | grestore 2448 | } bind def 2449 | 348.447 388.8 o 2450 | grestore 2451 | gsave 2452 | /o { 2453 | gsave 2454 | newpath 2455 | translate 2456 | 0.5 setlinewidth 2457 | 1 setlinejoin 2458 | 0 setlinecap 2459 | 0 0 m 2460 | 0 2 l 2461 | 2462 | gsave 2463 | 0.000 setgray 2464 | fill 2465 | grestore 2466 | stroke 2467 | grestore 2468 | } bind def 2469 | 362.39 43.2 o 2470 | grestore 2471 | gsave 2472 | /o { 2473 | gsave 2474 | newpath 2475 | translate 2476 | 0.5 setlinewidth 2477 | 1 setlinejoin 2478 | 0 setlinecap 2479 | 0 0 m 2480 | 0 -2 l 2481 | 2482 | gsave 2483 | 0.000 setgray 2484 | fill 2485 | grestore 2486 | stroke 2487 | grestore 2488 | } bind def 2489 | 362.39 388.8 o 2490 | grestore 2491 | gsave 2492 | /o { 2493 | gsave 2494 | newpath 2495 | translate 2496 | 0.5 setlinewidth 2497 | 1 setlinejoin 2498 | 0 setlinecap 2499 | 0 0 m 2500 | 0 2 l 2501 | 2502 | gsave 2503 | 0.000 setgray 2504 | fill 2505 | grestore 2506 | stroke 2507 | grestore 2508 | } bind def 2509 | 373.205 43.2 o 2510 | grestore 2511 | gsave 2512 | /o { 2513 | gsave 2514 | newpath 2515 | translate 2516 | 0.5 setlinewidth 2517 | 1 setlinejoin 2518 | 0 setlinecap 2519 | 0 0 m 2520 | 0 -2 l 2521 | 2522 | gsave 2523 | 0.000 setgray 2524 | fill 2525 | grestore 2526 | stroke 2527 | grestore 2528 | } bind def 2529 | 373.205 388.8 o 2530 | grestore 2531 | gsave 2532 | /o { 2533 | gsave 2534 | newpath 2535 | translate 2536 | 0.5 setlinewidth 2537 | 1 setlinejoin 2538 | 0 setlinecap 2539 | 0 0 m 2540 | 0 2 l 2541 | 2542 | gsave 2543 | 0.000 setgray 2544 | fill 2545 | grestore 2546 | stroke 2547 | grestore 2548 | } bind def 2549 | 382.042 43.2 o 2550 | grestore 2551 | gsave 2552 | /o { 2553 | gsave 2554 | newpath 2555 | translate 2556 | 0.5 setlinewidth 2557 | 1 setlinejoin 2558 | 0 setlinecap 2559 | 0 0 m 2560 | 0 -2 l 2561 | 2562 | gsave 2563 | 0.000 setgray 2564 | fill 2565 | grestore 2566 | stroke 2567 | grestore 2568 | } bind def 2569 | 382.042 388.8 o 2570 | grestore 2571 | gsave 2572 | /o { 2573 | gsave 2574 | newpath 2575 | translate 2576 | 0.5 setlinewidth 2577 | 1 setlinejoin 2578 | 0 setlinecap 2579 | 0 0 m 2580 | 0 2 l 2581 | 2582 | gsave 2583 | 0.000 setgray 2584 | fill 2585 | grestore 2586 | stroke 2587 | grestore 2588 | } bind def 2589 | 389.513 43.2 o 2590 | grestore 2591 | gsave 2592 | /o { 2593 | gsave 2594 | newpath 2595 | translate 2596 | 0.5 setlinewidth 2597 | 1 setlinejoin 2598 | 0 setlinecap 2599 | 0 0 m 2600 | 0 -2 l 2601 | 2602 | gsave 2603 | 0.000 setgray 2604 | fill 2605 | grestore 2606 | stroke 2607 | grestore 2608 | } bind def 2609 | 389.513 388.8 o 2610 | grestore 2611 | gsave 2612 | /o { 2613 | gsave 2614 | newpath 2615 | translate 2616 | 0.5 setlinewidth 2617 | 1 setlinejoin 2618 | 0 setlinecap 2619 | 0 0 m 2620 | 0 2 l 2621 | 2622 | gsave 2623 | 0.000 setgray 2624 | fill 2625 | grestore 2626 | stroke 2627 | grestore 2628 | } bind def 2629 | 395.985 43.2 o 2630 | grestore 2631 | gsave 2632 | /o { 2633 | gsave 2634 | newpath 2635 | translate 2636 | 0.5 setlinewidth 2637 | 1 setlinejoin 2638 | 0 setlinecap 2639 | 0 0 m 2640 | 0 -2 l 2641 | 2642 | gsave 2643 | 0.000 setgray 2644 | fill 2645 | grestore 2646 | stroke 2647 | grestore 2648 | } bind def 2649 | 395.985 388.8 o 2650 | grestore 2651 | gsave 2652 | /o { 2653 | gsave 2654 | newpath 2655 | translate 2656 | 0.5 setlinewidth 2657 | 1 setlinejoin 2658 | 0 setlinecap 2659 | 0 0 m 2660 | 0 2 l 2661 | 2662 | gsave 2663 | 0.000 setgray 2664 | fill 2665 | grestore 2666 | stroke 2667 | grestore 2668 | } bind def 2669 | 401.693 43.2 o 2670 | grestore 2671 | gsave 2672 | /o { 2673 | gsave 2674 | newpath 2675 | translate 2676 | 0.5 setlinewidth 2677 | 1 setlinejoin 2678 | 0 setlinecap 2679 | 0 0 m 2680 | 0 -2 l 2681 | 2682 | gsave 2683 | 0.000 setgray 2684 | fill 2685 | grestore 2686 | stroke 2687 | grestore 2688 | } bind def 2689 | 401.693 388.8 o 2690 | grestore 2691 | gsave 2692 | /o { 2693 | gsave 2694 | newpath 2695 | translate 2696 | 0.5 setlinewidth 2697 | 1 setlinejoin 2698 | 0 setlinecap 2699 | 0 0 m 2700 | 0 2 l 2701 | 2702 | gsave 2703 | 0.000 setgray 2704 | fill 2705 | grestore 2706 | stroke 2707 | grestore 2708 | } bind def 2709 | 440.395 43.2 o 2710 | grestore 2711 | gsave 2712 | /o { 2713 | gsave 2714 | newpath 2715 | translate 2716 | 0.5 setlinewidth 2717 | 1 setlinejoin 2718 | 0 setlinecap 2719 | 0 0 m 2720 | 0 -2 l 2721 | 2722 | gsave 2723 | 0.000 setgray 2724 | fill 2725 | grestore 2726 | stroke 2727 | grestore 2728 | } bind def 2729 | 440.395 388.8 o 2730 | grestore 2731 | gsave 2732 | /o { 2733 | gsave 2734 | newpath 2735 | translate 2736 | 0.5 setlinewidth 2737 | 1 setlinejoin 2738 | 0 setlinecap 2739 | 0 0 m 2740 | 0 2 l 2741 | 2742 | gsave 2743 | 0.000 setgray 2744 | fill 2745 | grestore 2746 | stroke 2747 | grestore 2748 | } bind def 2749 | 460.047 43.2 o 2750 | grestore 2751 | gsave 2752 | /o { 2753 | gsave 2754 | newpath 2755 | translate 2756 | 0.5 setlinewidth 2757 | 1 setlinejoin 2758 | 0 setlinecap 2759 | 0 0 m 2760 | 0 -2 l 2761 | 2762 | gsave 2763 | 0.000 setgray 2764 | fill 2765 | grestore 2766 | stroke 2767 | grestore 2768 | } bind def 2769 | 460.047 388.8 o 2770 | grestore 2771 | gsave 2772 | /o { 2773 | gsave 2774 | newpath 2775 | translate 2776 | 0.5 setlinewidth 2777 | 1 setlinejoin 2778 | 0 setlinecap 2779 | 0 0 m 2780 | 0 2 l 2781 | 2782 | gsave 2783 | 0.000 setgray 2784 | fill 2785 | grestore 2786 | stroke 2787 | grestore 2788 | } bind def 2789 | 473.99 43.2 o 2790 | grestore 2791 | gsave 2792 | /o { 2793 | gsave 2794 | newpath 2795 | translate 2796 | 0.5 setlinewidth 2797 | 1 setlinejoin 2798 | 0 setlinecap 2799 | 0 0 m 2800 | 0 -2 l 2801 | 2802 | gsave 2803 | 0.000 setgray 2804 | fill 2805 | grestore 2806 | stroke 2807 | grestore 2808 | } bind def 2809 | 473.99 388.8 o 2810 | grestore 2811 | gsave 2812 | /o { 2813 | gsave 2814 | newpath 2815 | translate 2816 | 0.5 setlinewidth 2817 | 1 setlinejoin 2818 | 0 setlinecap 2819 | 0 0 m 2820 | 0 2 l 2821 | 2822 | gsave 2823 | 0.000 setgray 2824 | fill 2825 | grestore 2826 | stroke 2827 | grestore 2828 | } bind def 2829 | 484.805 43.2 o 2830 | grestore 2831 | gsave 2832 | /o { 2833 | gsave 2834 | newpath 2835 | translate 2836 | 0.5 setlinewidth 2837 | 1 setlinejoin 2838 | 0 setlinecap 2839 | 0 0 m 2840 | 0 -2 l 2841 | 2842 | gsave 2843 | 0.000 setgray 2844 | fill 2845 | grestore 2846 | stroke 2847 | grestore 2848 | } bind def 2849 | 484.805 388.8 o 2850 | grestore 2851 | gsave 2852 | /o { 2853 | gsave 2854 | newpath 2855 | translate 2856 | 0.5 setlinewidth 2857 | 1 setlinejoin 2858 | 0 setlinecap 2859 | 0 0 m 2860 | 0 2 l 2861 | 2862 | gsave 2863 | 0.000 setgray 2864 | fill 2865 | grestore 2866 | stroke 2867 | grestore 2868 | } bind def 2869 | 493.642 43.2 o 2870 | grestore 2871 | gsave 2872 | /o { 2873 | gsave 2874 | newpath 2875 | translate 2876 | 0.5 setlinewidth 2877 | 1 setlinejoin 2878 | 0 setlinecap 2879 | 0 0 m 2880 | 0 -2 l 2881 | 2882 | gsave 2883 | 0.000 setgray 2884 | fill 2885 | grestore 2886 | stroke 2887 | grestore 2888 | } bind def 2889 | 493.642 388.8 o 2890 | grestore 2891 | gsave 2892 | /o { 2893 | gsave 2894 | newpath 2895 | translate 2896 | 0.5 setlinewidth 2897 | 1 setlinejoin 2898 | 0 setlinecap 2899 | 0 0 m 2900 | 0 2 l 2901 | 2902 | gsave 2903 | 0.000 setgray 2904 | fill 2905 | grestore 2906 | stroke 2907 | grestore 2908 | } bind def 2909 | 501.113 43.2 o 2910 | grestore 2911 | gsave 2912 | /o { 2913 | gsave 2914 | newpath 2915 | translate 2916 | 0.5 setlinewidth 2917 | 1 setlinejoin 2918 | 0 setlinecap 2919 | 0 0 m 2920 | 0 -2 l 2921 | 2922 | gsave 2923 | 0.000 setgray 2924 | fill 2925 | grestore 2926 | stroke 2927 | grestore 2928 | } bind def 2929 | 501.113 388.8 o 2930 | grestore 2931 | gsave 2932 | /o { 2933 | gsave 2934 | newpath 2935 | translate 2936 | 0.5 setlinewidth 2937 | 1 setlinejoin 2938 | 0 setlinecap 2939 | 0 0 m 2940 | 0 2 l 2941 | 2942 | gsave 2943 | 0.000 setgray 2944 | fill 2945 | grestore 2946 | stroke 2947 | grestore 2948 | } bind def 2949 | 507.585 43.2 o 2950 | grestore 2951 | gsave 2952 | /o { 2953 | gsave 2954 | newpath 2955 | translate 2956 | 0.5 setlinewidth 2957 | 1 setlinejoin 2958 | 0 setlinecap 2959 | 0 0 m 2960 | 0 -2 l 2961 | 2962 | gsave 2963 | 0.000 setgray 2964 | fill 2965 | grestore 2966 | stroke 2967 | grestore 2968 | } bind def 2969 | 507.585 388.8 o 2970 | grestore 2971 | gsave 2972 | /o { 2973 | gsave 2974 | newpath 2975 | translate 2976 | 0.5 setlinewidth 2977 | 1 setlinejoin 2978 | 0 setlinecap 2979 | 0 0 m 2980 | 0 2 l 2981 | 2982 | gsave 2983 | 0.000 setgray 2984 | fill 2985 | grestore 2986 | stroke 2987 | grestore 2988 | } bind def 2989 | 513.293 43.2 o 2990 | grestore 2991 | gsave 2992 | /o { 2993 | gsave 2994 | newpath 2995 | translate 2996 | 0.5 setlinewidth 2997 | 1 setlinejoin 2998 | 0 setlinecap 2999 | 0 0 m 3000 | 0 -2 l 3001 | 3002 | gsave 3003 | 0.000 setgray 3004 | fill 3005 | grestore 3006 | stroke 3007 | grestore 3008 | } bind def 3009 | 513.293 388.8 o 3010 | grestore 3011 | /BitstreamVeraSans-Roman findfont 3012 | 18.000 scalefont 3013 | setfont 3014 | gsave 3015 | 217.309375 1.528125 translate 3016 | 0.000000 rotate 3017 | 0.000000 0.000000 m /N glyphshow 3018 | 13.464844 0.000000 m /u glyphshow 3019 | 24.873047 0.000000 m /m glyphshow 3020 | 42.407227 0.000000 m /b glyphshow 3021 | 53.833008 0.000000 m /e glyphshow 3022 | 64.907227 0.000000 m /r glyphshow 3023 | 72.307617 0.000000 m /space glyphshow 3024 | 78.029297 0.000000 m /o glyphshow 3025 | 89.041992 0.000000 m /f glyphshow 3026 | 95.378906 0.000000 m /space glyphshow 3027 | 101.100586 0.000000 m /E glyphshow 3028 | 112.473633 0.000000 m /d glyphshow 3029 | 123.899414 0.000000 m /g glyphshow 3030 | 135.325195 0.000000 m /e glyphshow 3031 | 146.399414 0.000000 m /s glyphshow 3032 | grestore 3033 | gsave 3034 | /o { 3035 | gsave 3036 | newpath 3037 | translate 3038 | 0.5 setlinewidth 3039 | 1 setlinejoin 3040 | 0 setlinecap 3041 | 0 0 m 3042 | 4 0 l 3043 | 3044 | gsave 3045 | 0.000 setgray 3046 | fill 3047 | grestore 3048 | stroke 3049 | grestore 3050 | } bind def 3051 | 72 43.2 o 3052 | grestore 3053 | gsave 3054 | /o { 3055 | gsave 3056 | newpath 3057 | translate 3058 | 0.5 setlinewidth 3059 | 1 setlinejoin 3060 | 0 setlinecap 3061 | 0 0 m 3062 | -4 0 l 3063 | 3064 | gsave 3065 | 0.000 setgray 3066 | fill 3067 | grestore 3068 | stroke 3069 | grestore 3070 | } bind def 3071 | 518.4 43.2 o 3072 | grestore 3073 | gsave 3074 | 39.375000 38.239062 translate 3075 | 0.000000 rotate 3076 | 0.000000 0.000000 m /zero glyphshow 3077 | 11.452148 0.000000 m /period glyphshow 3078 | 17.173828 0.000000 m /zero glyphshow 3079 | grestore 3080 | gsave 3081 | /o { 3082 | gsave 3083 | newpath 3084 | translate 3085 | 0.5 setlinewidth 3086 | 1 setlinejoin 3087 | 0 setlinecap 3088 | 0 0 m 3089 | 4 0 l 3090 | 3091 | gsave 3092 | 0.000 setgray 3093 | fill 3094 | grestore 3095 | stroke 3096 | grestore 3097 | } bind def 3098 | 72 112.32 o 3099 | grestore 3100 | gsave 3101 | /o { 3102 | gsave 3103 | newpath 3104 | translate 3105 | 0.5 setlinewidth 3106 | 1 setlinejoin 3107 | 0 setlinecap 3108 | 0 0 m 3109 | -4 0 l 3110 | 3111 | gsave 3112 | 0.000 setgray 3113 | fill 3114 | grestore 3115 | stroke 3116 | grestore 3117 | } bind def 3118 | 518.4 112.32 o 3119 | grestore 3120 | gsave 3121 | 39.375000 107.359062 translate 3122 | 0.000000 rotate 3123 | 0.000000 0.000000 m /zero glyphshow 3124 | 11.452148 0.000000 m /period glyphshow 3125 | 17.173828 0.000000 m /five glyphshow 3126 | grestore 3127 | gsave 3128 | /o { 3129 | gsave 3130 | newpath 3131 | translate 3132 | 0.5 setlinewidth 3133 | 1 setlinejoin 3134 | 0 setlinecap 3135 | 0 0 m 3136 | 4 0 l 3137 | 3138 | gsave 3139 | 0.000 setgray 3140 | fill 3141 | grestore 3142 | stroke 3143 | grestore 3144 | } bind def 3145 | 72 181.44 o 3146 | grestore 3147 | gsave 3148 | /o { 3149 | gsave 3150 | newpath 3151 | translate 3152 | 0.5 setlinewidth 3153 | 1 setlinejoin 3154 | 0 setlinecap 3155 | 0 0 m 3156 | -4 0 l 3157 | 3158 | gsave 3159 | 0.000 setgray 3160 | fill 3161 | grestore 3162 | stroke 3163 | grestore 3164 | } bind def 3165 | 518.4 181.44 o 3166 | grestore 3167 | gsave 3168 | 39.375000 176.479062 translate 3169 | 0.000000 rotate 3170 | 0.000000 0.000000 m /one glyphshow 3171 | 11.452148 0.000000 m /period glyphshow 3172 | 17.173828 0.000000 m /zero glyphshow 3173 | grestore 3174 | gsave 3175 | /o { 3176 | gsave 3177 | newpath 3178 | translate 3179 | 0.5 setlinewidth 3180 | 1 setlinejoin 3181 | 0 setlinecap 3182 | 0 0 m 3183 | 4 0 l 3184 | 3185 | gsave 3186 | 0.000 setgray 3187 | fill 3188 | grestore 3189 | stroke 3190 | grestore 3191 | } bind def 3192 | 72 250.56 o 3193 | grestore 3194 | gsave 3195 | /o { 3196 | gsave 3197 | newpath 3198 | translate 3199 | 0.5 setlinewidth 3200 | 1 setlinejoin 3201 | 0 setlinecap 3202 | 0 0 m 3203 | -4 0 l 3204 | 3205 | gsave 3206 | 0.000 setgray 3207 | fill 3208 | grestore 3209 | stroke 3210 | grestore 3211 | } bind def 3212 | 518.4 250.56 o 3213 | grestore 3214 | gsave 3215 | 39.375000 245.599063 translate 3216 | 0.000000 rotate 3217 | 0.000000 0.000000 m /one glyphshow 3218 | 11.452148 0.000000 m /period glyphshow 3219 | 17.173828 0.000000 m /five glyphshow 3220 | grestore 3221 | gsave 3222 | /o { 3223 | gsave 3224 | newpath 3225 | translate 3226 | 0.5 setlinewidth 3227 | 1 setlinejoin 3228 | 0 setlinecap 3229 | 0 0 m 3230 | 4 0 l 3231 | 3232 | gsave 3233 | 0.000 setgray 3234 | fill 3235 | grestore 3236 | stroke 3237 | grestore 3238 | } bind def 3239 | 72 319.68 o 3240 | grestore 3241 | gsave 3242 | /o { 3243 | gsave 3244 | newpath 3245 | translate 3246 | 0.5 setlinewidth 3247 | 1 setlinejoin 3248 | 0 setlinecap 3249 | 0 0 m 3250 | -4 0 l 3251 | 3252 | gsave 3253 | 0.000 setgray 3254 | fill 3255 | grestore 3256 | stroke 3257 | grestore 3258 | } bind def 3259 | 518.4 319.68 o 3260 | grestore 3261 | gsave 3262 | 39.375000 314.719063 translate 3263 | 0.000000 rotate 3264 | 0.000000 0.000000 m /two glyphshow 3265 | 11.452148 0.000000 m /period glyphshow 3266 | 17.173828 0.000000 m /zero glyphshow 3267 | grestore 3268 | gsave 3269 | /o { 3270 | gsave 3271 | newpath 3272 | translate 3273 | 0.5 setlinewidth 3274 | 1 setlinejoin 3275 | 0 setlinecap 3276 | 0 0 m 3277 | 4 0 l 3278 | 3279 | gsave 3280 | 0.000 setgray 3281 | fill 3282 | grestore 3283 | stroke 3284 | grestore 3285 | } bind def 3286 | 72 388.8 o 3287 | grestore 3288 | gsave 3289 | /o { 3290 | gsave 3291 | newpath 3292 | translate 3293 | 0.5 setlinewidth 3294 | 1 setlinejoin 3295 | 0 setlinecap 3296 | 0 0 m 3297 | -4 0 l 3298 | 3299 | gsave 3300 | 0.000 setgray 3301 | fill 3302 | grestore 3303 | stroke 3304 | grestore 3305 | } bind def 3306 | 518.4 388.8 o 3307 | grestore 3308 | gsave 3309 | 39.375000 383.839063 translate 3310 | 0.000000 rotate 3311 | 0.000000 0.000000 m /two glyphshow 3312 | 11.452148 0.000000 m /period glyphshow 3313 | 17.173828 0.000000 m /five glyphshow 3314 | grestore 3315 | gsave 3316 | 30.625000 106.195312 translate 3317 | 90.000000 rotate 3318 | 0.000000 0.000000 m /N glyphshow 3319 | 13.464844 0.000000 m /u glyphshow 3320 | 24.873047 0.000000 m /m glyphshow 3321 | 42.407227 0.000000 m /b glyphshow 3322 | 53.833008 0.000000 m /e glyphshow 3323 | 64.907227 0.000000 m /r glyphshow 3324 | 72.307617 0.000000 m /space glyphshow 3325 | 78.029297 0.000000 m /o glyphshow 3326 | 89.041992 0.000000 m /f glyphshow 3327 | 95.378906 0.000000 m /space glyphshow 3328 | 101.100586 0.000000 m /R glyphshow 3329 | 113.607422 0.000000 m /o glyphshow 3330 | 124.620117 0.000000 m /u glyphshow 3331 | 136.028320 0.000000 m /n glyphshow 3332 | 147.436523 0.000000 m /d glyphshow 3333 | 158.862305 0.000000 m /s glyphshow 3334 | 168.240234 0.000000 m /slash glyphshow 3335 | 174.304688 0.000000 m /E glyphshow 3336 | 185.677734 0.000000 m /d glyphshow 3337 | 197.103516 0.000000 m /g glyphshow 3338 | 208.529297 0.000000 m /e glyphshow 3339 | grestore 3340 | 1.000 setlinewidth 3341 | 0 setlinejoin 3342 | gsave 3343 | 168.18375 307.32625 m 3344 | 507.6 307.32625 l 3345 | 507.6 378 l 3346 | 168.18375 378 l 3347 | cl 3348 | gsave 3349 | 1.000 setgray 3350 | fill 3351 | grestore 3352 | stroke 3353 | grestore 3354 | 1 setlinejoin 3355 | [6 6] 0 setdash 3356 | 0.000 0.500 0.000 setrgbcolor 3357 | gsave 3358 | 183.30375 360.20125 m 3359 | 213.54375 360.20125 l 3360 | stroke 3361 | grestore 3362 | 0.000 setgray 3363 | /BitstreamVeraSans-Roman findfont 3364 | 21.600 scalefont 3365 | setfont 3366 | gsave 3367 | 237.303750 352.641250 translate 3368 | 0.000000 rotate 3369 | 0.000000 0.000000 m /E glyphshow 3370 | 13.663452 0.000000 m /x glyphshow 3371 | 26.461060 0.000000 m /p glyphshow 3372 | 40.187866 0.000000 m /e glyphshow 3373 | 53.492310 0.000000 m /r glyphshow 3374 | 62.383057 0.000000 m /i glyphshow 3375 | 68.391174 0.000000 m /m glyphshow 3376 | 89.456543 0.000000 m /e glyphshow 3377 | 102.760986 0.000000 m /n glyphshow 3378 | 116.466675 0.000000 m /t glyphshow 3379 | 124.945618 0.000000 m /a glyphshow 3380 | 138.197266 0.000000 m /l glyphshow 3381 | 144.205383 0.000000 m /space glyphshow 3382 | 151.079346 0.000000 m /R glyphshow 3383 | 166.089294 0.000000 m /e glyphshow 3384 | 179.393738 0.000000 m /s glyphshow 3385 | 190.660278 0.000000 m /u glyphshow 3386 | 204.365967 0.000000 m /l glyphshow 3387 | 210.374084 0.000000 m /t glyphshow 3388 | grestore 3389 | 2 setlinecap 3390 | [] 0 setdash 3391 | 0.000 0.000 1.000 setrgbcolor 3392 | gsave 3393 | 183.30375 328.104375 m 3394 | 213.54375 328.104375 l 3395 | stroke 3396 | grestore 3397 | 0.500 setlinewidth 3398 | 0 setlinejoin 3399 | 0 setlinecap 3400 | 0.000 setgray 3401 | gsave 3402 | /o { 3403 | gsave 3404 | newpath 3405 | translate 3406 | 0.5 setlinewidth 3407 | 0 setlinejoin 3408 | 0 setlinecap 3409 | 0 3 m 3410 | -3 -3 l 3411 | 3 -3 l 3412 | cl 3413 | 3414 | gsave 3415 | 0.000 0.000 1.000 setrgbcolor 3416 | fill 3417 | grestore 3418 | stroke 3419 | grestore 3420 | } bind def 3421 | 183.304 328.104 o 3422 | 213.544 328.104 o 3423 | grestore 3424 | gsave 3425 | 237.303750 320.544375 translate 3426 | 0.000000 rotate 3427 | 0.000000 0.000000 m /F glyphshow 3428 | 12.422974 0.000000 m /i glyphshow 3429 | 18.431091 0.000000 m /t glyphshow 3430 | 26.910034 0.000000 m /colon glyphshow 3431 | 34.195801 0.000000 m /space glyphshow 3432 | 41.069763 0.000000 m /a glyphshow 3433 | 54.321411 0.000000 m /slash glyphshow 3434 | 61.607178 0.000000 m /x glyphshow 3435 | 74.404785 0.000000 m /asterisk glyphshow 3436 | 85.217285 0.000000 m /asterisk glyphshow 3437 | 96.029785 0.000000 m /parenleft glyphshow 3438 | 104.466492 0.000000 m /five glyphshow 3439 | 118.224976 0.000000 m /period glyphshow 3440 | 125.098938 0.000000 m /slash glyphshow 3441 | 132.384705 0.000000 m /nine glyphshow 3442 | 146.143188 0.000000 m /period glyphshow 3443 | 153.017151 0.000000 m /parenright glyphshow 3444 | 161.453857 0.000000 m /comma glyphshow 3445 | 168.327820 0.000000 m /a glyphshow 3446 | 181.579468 0.000000 m /equal glyphshow 3447 | 199.698853 0.000000 m /one glyphshow 3448 | 213.457336 0.000000 m /zero glyphshow 3449 | 227.215820 0.000000 m /period glyphshow 3450 | 234.089783 0.000000 m /one glyphshow 3451 | 247.848267 0.000000 m /four glyphshow 3452 | grestore 3453 | /BitstreamVeraSans-Roman findfont 3454 | 18.000 scalefont 3455 | setfont 3456 | gsave 3457 | 144.867188 409.688125 translate 3458 | 0.000000 rotate 3459 | 0.000000 0.000000 m /S glyphshow 3460 | 11.425781 0.000000 m /c glyphshow 3461 | 21.322266 0.000000 m /a glyphshow 3462 | 32.352539 0.000000 m /l glyphshow 3463 | 37.353516 0.000000 m /i glyphshow 3464 | 42.354492 0.000000 m /n glyphshow 3465 | 53.762695 0.000000 m /g glyphshow 3466 | 65.188477 0.000000 m /space glyphshow 3467 | 70.910156 0.000000 m /f glyphshow 3468 | 77.247070 0.000000 m /o glyphshow 3469 | 88.259766 0.000000 m /r glyphshow 3470 | 95.660156 0.000000 m /space glyphshow 3471 | 101.381836 0.000000 m /T glyphshow 3472 | 112.330078 0.000000 m /e glyphshow 3473 | 123.404297 0.000000 m /s glyphshow 3474 | 132.782227 0.000000 m /t glyphshow 3475 | 139.839844 0.000000 m /colon glyphshow 3476 | 145.904297 0.000000 m /space glyphshow 3477 | 151.625977 0.000000 m /g glyphshow 3478 | 163.051758 0.000000 m /r glyphshow 3479 | 170.452148 0.000000 m /i glyphshow 3480 | 175.453125 0.000000 m /d glyphshow 3481 | 186.878906 0.000000 m /comma glyphshow 3482 | 192.600586 0.000000 m /space glyphshow 3483 | 198.322266 0.000000 m /C glyphshow 3484 | 210.890625 0.000000 m /O glyphshow 3485 | 225.058594 0.000000 m /N glyphshow 3486 | 238.523438 0.000000 m /G glyphshow 3487 | 252.471680 0.000000 m /E glyphshow 3488 | 263.844727 0.000000 m /S glyphshow 3489 | 275.270508 0.000000 m /T glyphshow 3490 | grestore 3491 | 3492 | end 3493 | showpage 3494 | %%EOF 3495 | --------------------------------------------------------------------------------