Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

v0.2.1

* Added support for js expression in the `from` node addressing issue [#86](#86)
* Enhanced `JoinReferenceNode` performance in the default assert case where there are no `references` to left or right context.
* Added ability to use `or` and `not` in tandem to check for the non-existence of multiple facts. [#85](#85)
* Fixed issue with `from` node where an undefined property would be tested. [#89](#89)
* You can now define a custom resolution strategy.
* Compiling nools files now supports the from modifier.
* Documentation updates
   * Updates about from node support with js values.
   * New documentation about using `or` and `not` constratints together.
   * Updated `or` documentation to include a three constraint example.
  • Loading branch information...
commit 86eea5e7e506f4c356bb1d8d125b5c3cdfb4102f 1 parent e58883d
@doug-martin doug-martin authored
Showing with 10,705 additions and 422 deletions.
  1. +1 −1  Gruntfile.js
  2. +3 −2 benchmark/waltzDb/benchmark.js
  3. +2 −3 benchmark/waltzDb/waltzDb.nools
  4. +15 −0 docs/History.html
  5. +1,063 −0 docs/examples/browser/rules/waltzDb.nools
  6. +3,429 −0 docs/examples/browser/src/watlzdbData.js
  7. +143 −0 docs/examples/browser/waltzDb.html
  8. +166 −5 docs/index.html
  9. +8 −8 docs/nools.js
  10. +1,063 −0 examples/browser/rules/waltzDb.nools
  11. +3,429 −0 examples/browser/src/watlzdbData.js
  12. +143 −0 examples/browser/waltzDb.html
  13. +14 −0 history.md
  14. +5 −6 lib/agenda.js
  15. +34 −26 lib/compile/index.js
  16. +32 −11 lib/compile/transpile.js
  17. +6 −5 lib/constraint.js
  18. +11 −3 lib/constraintMatcher.js
  19. +1 −38 lib/extended.js
  20. +4 −2 lib/flow.js
  21. +9 −1 lib/flowContainer.js
  22. +1 −0  lib/nodes/alphaNode.js
  23. +4 −3 lib/nodes/equalityNode.js
  24. +11 −12 lib/nodes/fromNode.js
  25. +10 −10 lib/nodes/fromNotNode.js
  26. +3 −3 lib/nodes/joinNode.js
  27. +37 −21 lib/nodes/joinReferenceNode.js
  28. +41 −26 lib/nodes/notNode.js
  29. +3 −3 lib/nodes/typeNode.js
  30. +31 −6 lib/parser/nools/tokens.js
  31. +8 −4 lib/pattern.js
  32. +8 −3 lib/rule.js
  33. +262 −186 nools.js
  34. +8 −8 nools.min.js
  35. +1 −1  package.json
  36. +233 −5 readme.md
  37. +41 −4 test/flow.compiled.test.js
  38. +41 −1 test/flow.dsl.test.js
  39. +152 −3 test/flow.test.js
  40. +112 −11 test/issues.test.js
  41. +48 −0 test/noolsParser.test.js
  42. +31 −1 test/rules.test.js
  43. +19 −0 test/rules/orRule-notConditions-compiled.js
  44. +19 −0 test/rules/orRule-notConditions.nools
View
2  Gruntfile.js
@@ -30,7 +30,7 @@ module.exports = function (grunt) {
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;' +
' Licensed <%= pkg.license %> */\n',
- report: 'gzip'
+ report: 'min'
},
min: {
files: {
View
5 benchmark/waltzDb/benchmark.js
@@ -2,8 +2,9 @@
var data = require("./data"),
nools = require("../../index");
-var flow = nools.compile(__dirname + "/waltzDb.nools");
-var items = data.load(flow).waltzdb8;
+var flow = nools.compile(__dirname + "/waltzDb.nools")
+ .conflictResolution(["salience", "factRecency", "activationRecency"]);
+var items = data.load(flow).waltzdb4;
var session = flow.getSession.apply(flow, items);
session.assert(new (flow.getDefined("stage"))({value: "DUPLICATE"}));
var start = new Date();
View
5 benchmark/waltzDb/waltzDb.nools
@@ -78,8 +78,7 @@ function getAngle(p1, p2){
return PI/2;
else if (deltaY < 0)
return -PI/2;
- }
- else if (deltaY == 0) {
+ }else if (deltaY == 0) {
if (deltaX > 0)
return 0.0;
else if (deltaX < 0)
@@ -721,9 +720,9 @@ rule start_visit_2_junction {
junction : Junction junction.type == '2j' && junction.visited == 'no' {basePoint : basePoint, p1 : p1, p2 : p2};
}
then {
+ modify(junction, function(){ this.visited = "now";});
modify(stage, function(){ this.value = 'VISITING_2J';});
console.log( "VISITING_2J" );
- modify(junction, function(){ this.visited = "now";});
}
}
View
15 docs/History.html
@@ -178,6 +178,21 @@
+<h1>0.2.1</h1>
+<ul>
+<li>Added support for js expression in the <code>from</code> node addressing issue <a href="https://github.com/C2FO/nools/issues/86">#86</a></li>
+<li>Enhanced <code>JoinReferenceNode</code> performance in the default assert case where there are no <code>references</code> to left or right context.</li>
+<li>Added ability to use <code>or</code> and <code>not</code> in tandem to check for the non-existence of multiple facts. <a href="https://github.com/C2FO/nools/issues/85">#85</a></li>
+<li>Fixed issue with <code>from</code> node where an undefined property would be tested. <a href="https://github.com/C2FO/nools/issues/89">#89</a></li>
+<li>You can now define a custom resolution strategy.</li>
+<li>Compiling nools files now supports the from modifier.</li>
+<li>Documentation updates<ul>
+<li>Updates about from node support with js values.</li>
+<li>New documentation about using <code>or</code> and <code>not</code> constratints together.</li>
+<li>Updated <code>or</code> documentation to include a three constraint example.</li>
+</ul>
+</li>
+</ul>
<h1>0.2.0 / 2013-10-14</h1>
<ul>
<li>Nools now supports true modify!!!<ul>
View
1,063 docs/examples/browser/rules/waltzDb.nools
@@ -0,0 +1,1063 @@
+define Stage {
+ value : ""
+}
+
+define Line {
+ p1 : 0,
+ p2 : 0
+}
+
+define Edge{
+ type : "",
+ p1 : 0,
+ p2 : 0,
+ joined : false
+}
+
+define EdgeLabel{
+ p1 : 0,
+ p2 : 0,
+ labelName : "",
+ labelId : ""
+}
+
+define Junction {
+ p1 : 0,
+ p2 : 0,
+ p3 : 0,
+ basePoint : 0,
+ type : "",
+ name : "",
+ visited : "",
+ toString : function() {
+ return ["JUNCTION: P1=", this.p1, ",P2=", this.p2, ",P3=",
+ this.p3, ",BasePoint=", this.basePoint, ", Type=" + this.type,
+ ",Name=", this.name, ",Visited=", this.visited].join("");
+ }
+}
+
+define Label {
+ id : "",
+ type : "",
+ name : "",
+ n1 : "",
+ n2 : "",
+ n3 : ""
+}
+
+define Illegal {
+ basePoint : null,
+ labelId : ""
+}
+
+
+function getX(val){
+ return Math.floor(val / 100);
+}
+
+function getY(val){
+ return val % 100;
+}
+
+function getAngle(p1, p2){
+ //**********************************************************************
+ // This function is passed two points and calculates the angle between the
+ // line defined by these points and the x-axis.
+ //**********************************************************************/
+ var deltaX, deltaY, PI = Math.PI;
+
+ /* Calculate (x2 - x1) and (y2 - y1). The points are passed in the
+ * form x1y1 and x2y2. get_x() and get_y() are passed these points
+ * and return the x and y values respectively. For example,
+ * get_x(1020) returns 10. */
+ var deltaX = getX(p2) - getX(p1);
+ var deltaY = getY(p2) - getY(p1);
+
+ if (deltaX == 0) {
+ if (deltaY > 0)
+ return PI/2;
+ else if (deltaY < 0)
+ return -PI/2;
+ }else if (deltaY == 0) {
+ if (deltaX > 0)
+ return 0.0;
+ else if (deltaX < 0)
+ return PI;
+ }
+ else
+ return Math.atan2(deltaY, deltaX);
+}
+
+function getInscribedAngle(basePoint, p1, p2){
+ var angle1, angle2, temp, PI = Math.PI;
+
+ /* Get the angle between line #1 and the origin and the angle
+ * between line #2 and the origin, and then subtract these values. */
+ angle1 = getAngle(basePoint,p1),
+ angle2 = getAngle(basePoint,p2),
+ temp = angle1 - angle2;
+ if (temp < 0)
+ temp = -temp;
+
+ /* We always want the smaller of the two angles inscribed, so if the
+ * answer is greater than 180 degrees, calculate the smaller angle and
+ * return it. */
+ if (temp > PI)
+ temp = 2*PI - temp;
+ if (temp < 0)
+ return -temp;
+ return temp;
+}
+
+function make3Junction(junction, basePoint, p1, p2, p3){
+ var PI = Math.PI;
+ var angle12, angle13, angle23;
+ var sum, sum1213, sum1223, sum1323;
+ var delta;
+
+ angle12 = getInscribedAngle(basePoint,p1,p2);
+ angle13 = getInscribedAngle(basePoint,p1,p3);
+ angle23 = getInscribedAngle(basePoint,p2,p3);
+
+ sum1213 = angle12 + angle13;
+ sum1223 = angle12 + angle23;
+ sum1323 = angle13 + angle23;
+
+ if (sum1213 < sum1223) {
+ if (sum1213 < sum1323) {
+ sum = sum1213;
+ junction.p2 = p1; junction.p1 = p2; junction.p3 = p3;
+ }else {
+ sum = sum1323;
+ junction.p2 = p3; junction.p1 = p1; junction.p3 = p2;
+ }
+ }else {
+ if (sum1223 < sum1323) {
+ sum = sum1223;
+ junction.p2 = p2; junction.p1 = p1; junction.p3 = p3;
+ }
+ else {
+ sum = sum1323;
+ junction.p2 = p3; junction.p1 = p1; junction.p3 = p2;
+ }
+ }
+
+ delta = sum - PI;
+ if (delta < 0)
+ delta = -delta;
+
+ if (delta < 0.001)
+ junction.name = 'tee';
+ else if (sum > PI)
+ junction.name = 'fork';
+ else
+ junction.name = 'arrow';
+}
+
+
+
+// Reverse the edges
+//(p reverse_edges
+// (stage ^value duplicate)
+// (line ^p1 <p1> ^p2 <p2>)
+// -->
+// (make edge ^p1 <p1> ^p2 <p2> ^joined false)
+// (make edge ^p1 <p2> ^p2 <p1> ^joined false)
+// (remove 2))
+rule reverse_edges {
+ when {
+ stage : Stage stage.value == 'DUPLICATE';
+ line : Line {p1:p1, p2:p2};
+ }
+ then {
+ emit("log", "Edge " + p1 + " " + p2 );
+ emit("log", "Edge " + p2 + " " + p1 );
+ assert( new Edge({p1 : p1, p2 : p2, joined : false}) );
+ assert( new Edge({p1 : p2, p2 : p1, joined : false}) );
+ retract( line );
+ }
+}
+// Reversing is done
+//(p done_reversing
+// (stage ^value duplicate)
+// - (line)
+// -->
+// (modify 1 ^value detect_junctions))
+rule done_reversing {
+ when{
+ stage : Stage stage.value == 'DUPLICATE';
+ not(l : Line);
+ }
+ then {
+ modify(stage, function(){ this.value = 'DETECT_JUNCTIONS'});
+ emit("log", "DETECT_JUNCTIONS" );
+ }
+}
+
+
+//(p make_3_junction
+// (stage ^value detect_junctions)
+// (edge ^p1 <base_point> ^p2 <p1> ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p2> <> <p1>} ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p3> <> <p1> <> <p2>} ^joined false)
+// -->
+// (make junction
+// ^type 3j
+// ^name (make_3_junction <base_point> <p1> <p2> <p3>)
+// ^base_point <base_point>
+// ^visited no)
+// (modify 2 ^type 3j ^joined true)
+// (modify 3 ^type 3j ^joined true)
+// (modify 4 ^type 3j ^joined true))
+
+rule make_3_junction {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ edge1 : Edge edge1.joined == false {p1 : basePoint, p2 : p1};
+ edge2 : Edge edge2.joined == false && edge2.p1 == basePoint && edge2.p2 != p1 {p2 : p2};
+ edge3 : Edge edge3.joined == false && edge3.p1 == basePoint && edge3.p2 != p1 && edge3.p2 != p2 {p2 : p3};
+ }
+ then {
+ var junction = new Junction({
+ basePoint : basePoint,
+ type : '3j',
+ visited : "no"
+ });
+ make3Junction(junction, basePoint, p1, p2, p3);
+ assert( junction );
+ emit("log", junction.toString( ) );
+ modify( edge1, function(){this.joined = true; this.type = '3j';});
+ modify( edge2, function(){this.joined = true; this.type = '3j';});
+ modify( edge3, function(){this.joined = true; this.type = '3j';});
+ }
+}
+
+//(p make_L
+// (stage ^value detect_junctions)
+// (edge ^p1 <base_point> ^p2 <p2> ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p3> <> <p2>} ^joined false)
+// - (edge ^p1 <base_point> ^p2 {<> <p2> <> <p3>})
+// -->
+// (make junction
+// ^type 2j
+// ^name L
+// ^base_point <base_point>
+// ^p1 <p2>
+// ^p2 <p3>
+// ^visited no)
+// (modify 2 ^type 2j ^joined true)
+// (modify 3 ^type 2j ^joined true))
+
+rule make_L {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ edge1 : Edge edge1.joined == false {p1 : basePoint, p2 : p2};
+ edge2 : Edge edge2.p1 == basePoint && edge2.p2 != p2 && edge2.joined == false {p2 : p3};
+ not(e : Edge e.p1 == basePoint && e.p2 != p2 && e.p2 != p3 );
+ }
+ then {
+ var junction = new Junction({type : "2j", name : "L", basePoint : basePoint, p1 : p2, p2 : p3, visited : "no"} );
+ assert( junction );
+ emit("log", junction.toString() );
+ modify( edge1, function(){this.joined = true; this.type = "2j"});
+ modify( edge2, function(){this.joined = true; this.type = "2j"});
+ }
+}
+
+
+//(p done_detecting
+// (stage ^value detect_junctions)
+// - (edge ^joined false)
+// -->
+// (modify 1 ^value find_initial_boundary))
+rule done_detecting {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ not( e : Edge e.joined == false );
+ }
+ then {
+ modify(stage, function(){this.value = 'FIND_INITIAL_BOUNDARY' });
+ emit("log", "Stage: FIND_INITIAL_BOUNDARY" );
+ }
+}
+
+
+//(p initial_boundary_junction_L
+// (stage ^value find_initial_boundary)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// -(junction ^base_point > <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 1)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name B ^l_id 1)
+// (modify 1 ^value find_second_boundary))
+rule initial_boundary_junction_L {
+ when {
+ stage : Stage stage.value == 'FIND_INITIAL_BOUNDARY';
+ junction : Junction junction.type == '2j' {basePoint : basePoint, p1 : p1, p2 : p2};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ not(j : Junction j.type == '2j' && j.basePoint > basePoint );
+ }
+ then {
+ modify(junction, function(){ this.visited = "yes" });
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "1" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "B", labelId : "1" } ) );
+ modify(stage, function(){ this.value = 'FIND_SECOND_BOUNDARY' });
+ emit("log", "FIND_SECOND_BOUNDARY" );
+ }
+}
+
+//(p initial_boundary_junction_arrow
+// (stage ^value find_initial_boundary)
+// (junction ^type 3j ^name arrow ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p3>)
+// -(junction ^base_point > <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name + ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name B ^l_id 14)
+// (modify 1 ^value find_second_boundary))
+rule initial_boundary_junction_arrow {
+ when {
+ stage : Stage stage.value == 'FIND_INITIAL_BOUNDARY';
+ junction : Junction junction.type == '3j' && junction.name == 'arrow' {basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ edge1 : Edge edge1.p1 == basePoint && edge1.p2 == p1;
+ edge2 : Edge edge2.p1 == basePoint && edge2.p2 == p2;
+ edge3 : Edge edge3.p1 == basePoint && edge3.p2 == p3;
+ not(j : Junction j.basePoint > basePoint);
+ }
+ then {
+ modify( junction, function(){this.visited = "yes";});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "+", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : "B", labelId :"14" }) );
+ modify( stage, function() {this.value = 'FIND_SECOND_BOUNDARY';});
+ emit("log", "FIND_SECOND_BOUNDARY" );
+ }
+}
+
+
+//(p second_boundary_junction_L
+// (stage ^value find_second_boundary)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// -(junction ^base_point < <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 1)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name B ^l_id 1)
+// (modify 1 ^value labeling))
+
+rule second_boundary_junction_L {
+ when {
+ stage : Stage stage.value == 'FIND_SECOND_BOUNDARY';
+ junction : Junction junction.type == '2j' {basePoint : basePoint, p1 : p1, p2 : p2};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ not(j : Junction j.basePoint < basePoint);
+ }
+ then {
+ modify(junction, function(){ this.visited = "yes"});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "1" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "B", labelId : "1" }) );
+ modify(stage, function(){this.value = 'LABELING';});
+ emit("log", "LABELING" );
+ }
+}
+
+//(p second_boundary_junction_arrow
+// (stage ^value find_second_boundary)
+// (junction ^type 3j ^name arrow ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p3>)
+// -(junction ^base_point < <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name + ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name B ^l_id 14)
+// (modify 1 ^value labeling))
+rule second_boundary_junction_arrow {
+ when {
+ stage : Stage stage.value == 'FIND_SECOND_BOUNDARY';
+ junction : Junction junction.type == '3j' && junction.name == 'arrow' {basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ e3 : Edge e3.p1 == basePoint && e3.p2 == p3;
+ not(j : Junction j.basePoint < basePoint);
+ }
+ then {
+ modify( junction, function(){this.visited = "yes"});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "+", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : "B", labelId : "14" }) );
+ modify( stage, function(){this.value = 'LABELING'});
+ emit("log", "LABELING" );
+ }
+}
+
+
+//(p start_visit_3_junction
+// (stage ^value labeling)
+// (junction ^base_point <bp> ^type 3j ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited no)
+// -->
+// (modify 1 ^value visiting_3j)
+// (modify 2 ^visited now))
+
+rule start_visit_3_junction {
+ when {
+ stage : Stage stage.value == 'LABELING';
+ junction : Junction junction.type == '3j' && junction.visited == 'no'
+ }
+ then {
+ modify(stage, function(){this.value = 'VISITING_3J'});
+ modify(junction, function(){ this.visited = "now"});
+ emit("log", "VISITING_3J" );
+ }
+}
+
+
+//(p visit_3j_0
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_0 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_1
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_1 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint );
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_2
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_2 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_3
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_3 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_4
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_4 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_5
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_5 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_6
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_6 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not( el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_7
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_7 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not( el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p start_visit_2_junction
+// (stage ^value labeling)
+// (junction ^base_point <bp> ^type 2j ^p1 <p1> ^p2 <p2> ^visited no)
+// -->
+// (modify 1 ^value visiting_2j)
+// (modify 2 ^visited now))
+rule start_visit_2_junction {
+ when {
+ stage : Stage stage.value == 'LABELING';
+ junction : Junction junction.type == '2j' && junction.visited == 'no' {basePoint : basePoint, p1 : p1, p2 : p2};
+ }
+ then {
+ modify(junction, function(){ this.visited = "now";});
+ modify(stage, function(){ this.value = 'VISITING_2J';});
+ emit("log", "VISITING_2J" );
+ }
+}
+
+//(p visit_2j_0
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_0 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p visit_2j_1
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_1 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+
+//(p visit_2j_2
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_2 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p visit_2j_3
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_3 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not(el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p end_visit
+// (stage ^value << visiting_3j visiting_2j >>)
+// (junction ^visited now)
+// -->
+// (modify 1 ^value marking))
+rule end_visit {
+ when {
+ stage : Stage stage.value == 'VISITING_2J' || stage.value == 'VISITING_3J';
+ junction : Junction junction.visited == 'now';
+ }
+ then {
+ modify(stage, function(){ this.value = 'MARKING';});
+ emit("log", "MARKING" );
+ }
+}
+
+//(p marking
+// (stage ^value marking)
+// (junction ^base_point <bp> ^visited now)
+// (edge ^p1 <p> ^p2 <bp>)
+// (junction ^base_point <p> ^visited yes)
+// -->
+// (modify 4 ^visited check))
+rule marking {
+ when {
+ s : Stage s.value == 'MARKING';
+ j : Junction j.visited == now {basePoint : basePoint};
+ e : Edge e.p2 == basePoint {p1 : p1};
+ junction : Junction junction.basePoint == p1 && junction.visited == 'yes';
+ }
+ then {
+ modify(junction, function(){ this.visited = "check"});
+ }
+}
+
+
+//(p stop_marking
+// (stage ^value marking)
+// (junction ^base_point <bp> ^visited now)
+// -->
+// (modify 2 ^visited yes))
+rule stop_marking {
+ when {
+ s : Stage s.value == 'MARKING';
+ junction : Junction junction.visited == 'now' {basePoint : basePoint};
+ }
+ then {
+ modify(junction, function(){this.visited = "yes"});
+ }
+}
+
+
+//(p start_checking
+// (stage ^value marking)
+// -->
+// (modify 1 ^value checking))
+//
+rule start_checking {
+ when {
+ stage : Stage stage.value == 'MARKING';
+ }
+ then {
+ modify(stage, function(){this.value = 'CHECKING';});
+ emit("log", "CHECKING" );
+ }
+}
+
+//(p checking
+// (stage ^value checking)
+// (junction ^base_point <bp> ^visited check)
+// (edge_label ^p1 <bp> ^p2 <p> ^l_name <n> ^l_id <id>)
+// (junction ^base_point <p> ^visited yes)
+// -(edge_label ^p1 <p> ^p2 <bp> ^l_name <n>)
+// -->
+// (modify 1 ^value remove_label)
+// (make illegal ^bp <bp> ^l_id <id>))
+rule checking {
+ when {
+ stage : Stage stage.value == 'CHECKING';
+ junction : Junction junction.visited == 'check' {basePoint : basePoint};
+ el1 : EdgeLabel el1.p1 == basePoint {p2 : p2, labelName : labelName, labelId : labelId};
+ j : Junction j.basePoint == p2 && j.visited == 'yes';
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == labelName);
+ }
+ then {
+ modify(stage, function(){this.value = 'REMOVE_LABEL';});
+ emit("log", "REMOVE_LABEL" );
+ assert ( new Illegal({basePoint : basePoint, labelId : labelId}) );
+ }
+}
+
+//(p remove_label_3j
+// (stage ^value remove_label)
+// (illegal ^bp <bp> ^l_id <id>)
+// (junction ^type 3j ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge_label ^p1 <bp> ^p2 <p1> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p2> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p3> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <id> (crlf))
+// ; (write edge_label <bp> <p2> <id> (crlf))
+// (modify 1 ^value checking)
+// (remove 2)
+// (remove 4)
+// (remove 5)
+// (remove 6))
+rule remove_label_3j {
+ when {
+ stage : Stage stage.value == 'REMOVE_LABEL';
+ illegal : Illegal {basePoint : basePoint, labelId : labelId};
+ j : Junction j.type == '3j' && j.basePoint == basePoint {p1 : p1, p2 : p2, p3 : p3};
+ edgeLabel1 : EdgeLabel edgeLabel1.p1 == basePoint && edgeLabel1.p2 == p1 && edgeLabel1.labelId == labelId;
+ edgeLabel2 : EdgeLabel edgeLabel2.p1 == basePoint && edgeLabel2.p2 == p2 && edgeLabel2.labelId == labelId;
+ edgeLabel3 : EdgeLabel edgeLabel3.p1 == basePoint && edgeLabel3.p2 == p3 && edgeLabel3.labelId == labelId;
+ }
+ then {
+ modify( stage, function(){this.value = 'CHECKING';});
+ emit("log", "CHECKING" );
+ retract( illegal );
+ retract( edgeLabel1 );
+ retract( edgeLabel2 );
+ retract( edgeLabel3 );
+ }
+}
+
+//(p remove_edge_2j
+// (stage ^value remove_label)
+// (illegal ^bp <bp> ^l_id <id>)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge_label ^p1 <bp> ^p2 <p1> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p2> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (modify 1 ^value checking)
+// (remove 2)
+// (remove 4)
+// (remove 5))
+rule remove_edge_2j {
+ when {
+ stage : Stage stage.value == 'REMOVE_LABEL';
+ illegal : Illegal {basePoint : basePoint, labelId : labelId};
+ j : Junction j.type == '2j' && j.basePoint == basePoint {p1 : p1, p2 : p2};
+ edgeLabel1 : EdgeLabel edgeLabel1.p1 == basePoint && edgeLabel1.p2 == p1 && edgeLabel1.labelId == labelId;
+ edgeLabel2 : EdgeLabel edgeLabel2.p1 == basePoint && edgeLabel2.p2 == p2 && edgeLabel2.labelId == labelId;
+ }
+ then {
+ modify(stage, function(){this.value = 'CHECKING';});
+ emit("log", "CHECKING" );
+ retract( illegal );
+ retract( edgeLabel1 );
+ retract( edgeLabel2 );
+ }
+}
+
+
+//(p checking
+// (stage ^value checking)
+// (junction ^base_point <bp> ^visited check)
+// -->
+// (modify 2 ^visited yes))
+
+rule checking2 {
+ when {
+ s : Stage s.value == 'CHECKING';
+ junction : Junction junction.visited == 'check' {basePoint : basePoint};
+ }
+ then {
+ modify(junction, function(){this.visited = "yes"});
+ }
+}
+
+
+//(p stop_checking
+// (stage ^value checking)
+// -->
+// (modify 1 ^value labeling))
+rule stop_checking {
+ when {
+ stage : Stage stage.value == 'CHECKING';
+ }
+ then {
+ modify(stage, function(){this.value = 'LABELING'});
+ emit("log", "LABELING" );
+ }
+}
+
+
+//(p done_labeling
+// (stage ^value labeling)
+// -->
+// (modify 1 ^value printing))
+rule done_labeling {
+ when {
+ stage : Stage stage.value == 'LABELING'
+ }
+ then {
+ modify(stage, function(){this.value = 'PRINTING';});
+ emit("log", "PRINTING" );
+ }
+}
+
+
+//(p done
+// (stage ^value printing)
+// -->
+// (halt))
+rule done {
+ when {
+ stage : Stage stage.value == 'PRINTING'
+ }
+ then {
+ emit("log", "FINISHED" );
+ }
+}
View
3,429 docs/examples/browser/src/watlzdbData.js
3,429 additions, 0 deletions not shown
View
143 docs/examples/browser/waltzDb.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link type="text/css" rel="stylesheet" href="assets/conways.css">
+ <link type="text/css" rel="stylesheet" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
+ <link href='http://fonts.googleapis.com/css?family=Londrina+Shadow' rel='stylesheet' type='text/css'>
+ <title>WaltzDB Benchmark</title>
+</head>
+<body>
+
+
+<div id="manners" class="middle">
+ <h1>WaltzDB Benchmark</h1>
+
+ <form>
+
+ <select id="data">
+ <option value="waltzdb4">Waltzdb 4</option>
+ <option value="waltzdb8">Waltzdb 8</option>
+ <option value="waltzdb12">Waltzdb 12</option>
+ <option value="waltzdb16">Waltzdb 16</option>
+ </select>
+ <input type="submit" value="Run"/>
+ <input type="button" id="edit" value="Edit Rules"/>
+
+ <div class="middle" id="results_container">
+ </div>
+
+ </form>
+
+</div>
+
+<div id="editor-dialog">
+ <div id="editor"></div>
+</div>
+
+<script type="text/javascript" src="//code.jquery.com/jquery-1.10.1.min.js"></script>
+<script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
+<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ace/0.2.0/ace.js"></script>
+<script type="text/javascript" src="../../nools.js"></script>
+<script type="text/javascript" src="./src/common.js"></script>
+<script type="text/javascript" src="./src/watlzdbData.js"></script>
+<script type="text/javascript">
+
+ $(document).ready(function () {
+ $.ajax({
+ url: "./rules/waltzDb.nools"
+ }).then(function (res) {
+
+ var session, dataset,
+ resultsContainer = $("#results_container"),
+ statsListener = stats(),
+ flowStr = res,
+ flow = nools.compile(res, {name: "waltzDb"});
+
+ function stop() {
+ if (session) {
+ session.dispose();
+ resultsContainer.empty();
+ session = null;
+ }
+ }
+
+ function createSeat(seating) {
+ return $("<div/>", {
+ text: seating.toString()
+ });
+ }
+
+ function run() {
+ stop();
+ console.profile();
+ var data = loadData(flow, dataset);
+ session = statsListener.listen(flow.getSession());
+ for (var i = 0, l = data.length; i < l; i++) {
+ session.assert(data[i]);
+ }
+ session.assert(new (flow.getDefined("stage"))({value: "DUPLICATE"}));
+ session
+ .on("log", function (data) {
+ resultsContainer.append(data + "</br>");
+ resultsContainer.scrollTop(resultsContainer.scrollHeight);
+ })
+ .match().then(function () {
+ console.profileEnd();
+ console.log("done");
+ }, function (e) {
+ console.log(e.stack);
+ })
+ }
+
+
+ var statsListener = stats();
+ //setup grid;
+
+ var $select = $("#data");
+
+ $select.on("change", function () {
+ stop();
+ dataset = $(this).val();
+ });
+
+ $select.val("waltzdb4").trigger("change");
+
+ $("form").on("submit", function () {
+ run();
+ return false;
+ });
+
+ $("#edit").on("click", function () {
+ $("#editor-dialog").dialog("open");
+ return false;
+ });
+
+ $("#editor-dialog").dialog({
+ autoOpen: false,
+ modal: true,
+ width: window.innerWidth * 0.9,
+ height: window.innerHeight * 0.9,
+ open: function () {
+ (editor = ace.edit("editor").getSession()).setValue(flowStr);
+ },
+ buttons: {
+ "Save": function () {
+ $(this).dialog("close");
+ nools.deleteFlow("manners");
+ stop();
+ flow = nools.compile((flowStr = editor.getValue()), {name: "manners"});
+ },
+ Cancel: function () {
+ $(this).dialog("close");
+ }
+ }
+ });
+
+ });
+ });
+</script>
+
+</body>
+</html>
View
171 docs/index.html
@@ -207,6 +207,7 @@
<li><a href="#agenda-groups-auto-focus">Auto Focus</a></li>
</ul>
</li>
+<li><a href="#conflict-resolution">Conflict Resolution</a></li>
</ul>
</li>
<li><a href="#defining-rule">Defining Rules</a><ul>
@@ -745,6 +746,101 @@
.then(function () {
console.log(fired); //[&quot;Bootstrap&quot;, &quot;A to B&quot;, &quot;B to C&quot;, &quot;B to D&quot;]
});</code></pre>
+<p><a name="conflict-resolution"></a></p>
+<h2>Conflict Resolution</h2>
+<p>When declaring a flow it is defined with a default conflict resolution strategy. A conflict resolution strategy is used to determine which rule to activate when multiple rules are ready to be activated at the same time.</p>
+<h3>Resolution Strategies</h3>
+<ul>
+<li><code>salience</code> - sort activations on the specified <a href="#rule-salience"><code>salience</code></a>. (<strong>NOTE</strong> The default salience of a rule is 0).</li>
+<li><code>activationRecency</code> - sort activations on activation recency. This is a <code>LIFO</code> strategy the latest activation takes precedence.</li>
+<li><code>factRecency</code> - sort activations based on <code>fact</code> recency. Each time a fact is <code>asserted</code> or <code>modified</code> its recency is incremented.</li>
+<li><code>bucketCounter</code> - sort activations on the internal <code>bucket</code> counter. The bucket counter is incremented after an activation is fired and the internal <code>workingMemory</code> is altered.</li>
+</ul>
+<p>The default conflict resolution strategy consists of <code>salience</code> and <code>activationRecency</code>.</p>
+<h3>Examples</h3>
+<p><strong>Example 1</strong></p>
+<pre class='prettyprint linenums lang-js'><code>//activation 1
+{
+ salience: 0,
+ activationRecency: 1
+}
+
+//activation 2
+{
+ salience: 0,
+ activationRecency: 2
+}</code></pre>
+<p>In the above example activation 2 would be fired since it is the most recent activation an the rule salience is the same.</p>
+<p><strong>Example 2</strong></p>
+<pre class='prettyprint linenums lang-js'><code>//activation 1
+{
+ salience: 1,
+ activationRecency: 1
+}
+
+//activation 2
+{
+ salience: 0,
+ activationRecency: 2
+}</code></pre>
+<p>In this example activation 1 would fire because it has a greater salience</p>
+<h3>Overidding The Default Strategy</h3>
+<p>To override the default strategy you can use the <code>conflictResolution</code> method on a flow.</p>
+<pre class='prettyprint linenums lang-js'><code class="lang-javascript">
+var flow = nools.flow(/**define your flow**/);
+
+flow.conflictResolution([&quot;salience&quot;, &quot;factRecency&quot;, &quot;activationRecency&quot;]);</code></pre>
+<p>The combination of <code>salience</code>, <code>factRecency</code>, and <code>activationRecency</code> would do the following.</p>
+<ol>
+<li>Check if the salience is the same, if not use the activation with the greatest salience.</li>
+<li>If salience is the same check if fact recency is the same. The fact recency is determined by looping through the facts in each activation and until two different recencies are found. The activation with the greatest recency takes precendence.</li>
+<li>If fact recency is the same check the activation recency.</li>
+</ol>
+<p><strong>Example 1</strong></p>
+<pre class='prettyprint linenums lang-js'><code>//activation 1
+{
+ salience: 2,
+ factRecency: [1,2,3],
+ activationRecency: 1
+}
+
+//activation 2
+{
+ salience: 1,
+ factRecency: [1,2,4],
+ activationRecency: 2
+}</code></pre>
+<p>In this example activation 1 would fire because it&#39;s salience is the greatest.</p>
+<p><strong>Example 2</strong></p>
+<pre class='prettyprint linenums lang-js'><code>//activation 1
+{
+ salience: 1,
+ factRecency: [1,2,3],
+ activationRecency: 1
+}
+
+//activation 2
+{
+ salience: 1,
+ factRecency: [1,2,4],
+ activationRecency: 2
+}</code></pre>
+<p>In Example 2 activation 2 would fire because of the third recency entry.</p>
+<p><strong>Example 3</strong></p>
+<pre class='prettyprint linenums lang-js'><code>//activation 1
+{
+ salience: 2,
+ factRecency: [1,2,3],
+ activationRecency: 1
+}
+
+//activation 2
+{
+ salience: 1,
+ factRecency: [1,2,3],
+ activationRecency: 2
+}</code></pre>
+<p>In Example 3 activation 2 would fire because <code>salience</code> and <code>factRecency</code> are the same but activation 2&#39;s activation recency is greater.</p>
<p><a name="defining-rule"></a></p>
<h1>Defining rules</h1>
<p><a name="rule structure"></a></p>
@@ -986,25 +1082,59 @@
<p>The previous example will check that for all numbers in the <code>workingMemory</code> there is <strong>not</strong> one that is greater than <code>n1</code>.</p>
<p><a name="or-constraint"></a></p>
<h4>Or Constraint</h4>
-<p>The <code>or</code> constraint can be used to check for either one fact or another.</p>
+<p>The <code>or</code> constraint can be used to check for the existence of multiple facts.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">
[
[&quot;or&quot;,
[String, &quot;s&quot;, &quot;s == &#39;hello&#39;&quot;],
- [String, &quot;s&quot;, &quot;s == &#39;world&#39;&quot;]
+ [String, &quot;s&quot;, &quot;s == &#39;world&#39;&quot;],
+ [String, &quot;s&quot;, &quot;s == &#39;hello world&#39;&quot;]
]
]</code></pre>
<p>Using the DSL.</p>
<pre class='prettyprint linenums lang-js'><code>when {
or(
s : String s == &#39;hello&#39;,
- s : String s == &#39;world&#39;
+ s : String s == &#39;world&#39;,
+ s : String s == &#39;hello world&#39;
);
}</code></pre>
-<p>The previous example will evaluate to <code>true</code> if you have a string in <code>workingMemory</code> that equals <code>hello</code> or `world.</p>
+<p>The previous example will evaluate to <code>true</code> if you have a string in <code>workingMemory</code> that equals <code>hello</code>, <code>world, or &#39;hello world</code>.</p>
+<p><strong>Or with Not</strong></p>
+<p>The <code>or</code> constraint can be combined with a <code>not</code> constraint to allow for the checking of multiple not conditions without the implcit and.</p>
+<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var flow = nools.flow(&quot;or condition with not conditions&quot;, function (flow) {
+ flow.rule(&quot;hello rule&quot;, [
+ [&quot;or&quot;,
+ [&quot;not&quot;, Number, &quot;n1&quot;, &quot;n1 == 1&quot;],
+ [&quot;not&quot;, String, &quot;s1&quot;, &quot;s1 == &#39;hello&#39;&quot;],
+ [&quot;not&quot;, Date, &quot;d1&quot;, &quot;d1.getDate() == now().getDate()&quot;]
+ ],
+ [Count, &quot;called&quot;, null]
+ ], function (facts) {
+ facts.called.called++;
+ });
+ });
+});</code></pre>
+<p>or using the dsl.</p>
+<pre class='prettyprint linenums lang-js'><code>rule MultiNotOrRule {
+ when {
+ or (
+ not(n1: Number n1 == 1),
+ not(s1: String s1 == &#39;hello&#39;),
+ not(d1: Date d1.getDate() == now().getDate())
+ );
+ c: Count;
+ }
+ then{
+ c.called++;
+ }
+}</code></pre>
+<p><strong>Note</strong> Using the <code>or</code> with a <code>not</code> will cause the activation to fire for each <code>not</code> condition that passes. In the above examples if none of the three facts existed then the rule would fire three times.</p>
<p><a name="from-constraint"></a></p>
<h4>From Constraint</h4>
-<p>The <code>from</code> modifier allows for the checking of facts that are not necessarily in the <code>workingMemory</code> but instead exist as a property on a fact.</p>
+<p>The <code>from</code> modifier allows for the checking of facts that are not necessarily in the <code>workingMemory</code>.</p>
+<p>The <code>from</code> modifier can be used to access properties on a <code>fact</code> in <code>workingMemory</code> or you can use javascript expressions.</p>
+<p>To access properties on a fact you can use the fact name and the property you wish to use as the source for the <code>from</code> source.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">[
[Person, &quot;p&quot;],
[Address, &quot;a&quot;, &quot;a.zipcode == 88847&quot;, &quot;from p.address&quot;],
@@ -1038,6 +1168,37 @@
p: Person;
friend: Person friend in p.friends &amp;&amp; friend.firstName != p.firstName &amp;&amp; p.firstName =~ /^a/;
}</code></pre>
+<p>To specify the from source as an expression you can do the following.</p>
+<pre class='prettyprint linenums lang-js'><code class="lang-javascript">[
+ [Number, &quot;n1&quot;, &quot;from [1,2,3,4,5]&quot;]
+]</code></pre>
+<p>Or using the dsl</p>
+<pre class='prettyprint linenums lang-js'><code>{
+ n1: Number from [1,2,3,4,5];
+}</code></pre>
+<p>Using the above syntax you could use <code>from</code> to bootstrap data.</p>
+<p>You can also use any function defined in the scope of the <code>rule</code> or <code>flow</code></p>
+<pre class='prettyprint linenums lang-js'><code class="lang-javascript">
+flow.rule(&quot;my rule&quot;, {
+ scope: {
+ myArr: function(){
+ return [1,2,3,4,5];
+ }
+ },
+ [Number, &quot;n1&quot;, &quot;from myArr()&quot;],
+ function(facts){
+ this.assert(facts.n1);
+ }
+}</code></pre>
+<p>Or using the dsl and the <a href="#rule-scope">scope</a> option.</p>
+<pre class='prettyprint linenums lang-js'><code>rule &quot;my rule&quot;, {
+ when {
+ n1: Number from myArr();
+ }
+ then{
+ assert(n1);
+ }
+}</code></pre>
<p><a name="action"></a></p>
<h3>Action</h3>
<p>The action is a function that should be fired when all patterns in the rule match. The action is called in the scope
View
16 docs/nools.js
8 additions, 8 deletions not shown
View
1,063 examples/browser/rules/waltzDb.nools
@@ -0,0 +1,1063 @@
+define Stage {
+ value : ""
+}
+
+define Line {
+ p1 : 0,
+ p2 : 0
+}
+
+define Edge{
+ type : "",
+ p1 : 0,
+ p2 : 0,
+ joined : false
+}
+
+define EdgeLabel{
+ p1 : 0,
+ p2 : 0,
+ labelName : "",
+ labelId : ""
+}
+
+define Junction {
+ p1 : 0,
+ p2 : 0,
+ p3 : 0,
+ basePoint : 0,
+ type : "",
+ name : "",
+ visited : "",
+ toString : function() {
+ return ["JUNCTION: P1=", this.p1, ",P2=", this.p2, ",P3=",
+ this.p3, ",BasePoint=", this.basePoint, ", Type=" + this.type,
+ ",Name=", this.name, ",Visited=", this.visited].join("");
+ }
+}
+
+define Label {
+ id : "",
+ type : "",
+ name : "",
+ n1 : "",
+ n2 : "",
+ n3 : ""
+}
+
+define Illegal {
+ basePoint : null,
+ labelId : ""
+}
+
+
+function getX(val){
+ return Math.floor(val / 100);
+}
+
+function getY(val){
+ return val % 100;
+}
+
+function getAngle(p1, p2){
+ //**********************************************************************
+ // This function is passed two points and calculates the angle between the
+ // line defined by these points and the x-axis.
+ //**********************************************************************/
+ var deltaX, deltaY, PI = Math.PI;
+
+ /* Calculate (x2 - x1) and (y2 - y1). The points are passed in the
+ * form x1y1 and x2y2. get_x() and get_y() are passed these points
+ * and return the x and y values respectively. For example,
+ * get_x(1020) returns 10. */
+ var deltaX = getX(p2) - getX(p1);
+ var deltaY = getY(p2) - getY(p1);
+
+ if (deltaX == 0) {
+ if (deltaY > 0)
+ return PI/2;
+ else if (deltaY < 0)
+ return -PI/2;
+ }else if (deltaY == 0) {
+ if (deltaX > 0)
+ return 0.0;
+ else if (deltaX < 0)
+ return PI;
+ }
+ else
+ return Math.atan2(deltaY, deltaX);
+}
+
+function getInscribedAngle(basePoint, p1, p2){
+ var angle1, angle2, temp, PI = Math.PI;
+
+ /* Get the angle between line #1 and the origin and the angle
+ * between line #2 and the origin, and then subtract these values. */
+ angle1 = getAngle(basePoint,p1),
+ angle2 = getAngle(basePoint,p2),
+ temp = angle1 - angle2;
+ if (temp < 0)
+ temp = -temp;
+
+ /* We always want the smaller of the two angles inscribed, so if the
+ * answer is greater than 180 degrees, calculate the smaller angle and
+ * return it. */
+ if (temp > PI)
+ temp = 2*PI - temp;
+ if (temp < 0)
+ return -temp;
+ return temp;
+}
+
+function make3Junction(junction, basePoint, p1, p2, p3){
+ var PI = Math.PI;
+ var angle12, angle13, angle23;
+ var sum, sum1213, sum1223, sum1323;
+ var delta;
+
+ angle12 = getInscribedAngle(basePoint,p1,p2);
+ angle13 = getInscribedAngle(basePoint,p1,p3);
+ angle23 = getInscribedAngle(basePoint,p2,p3);
+
+ sum1213 = angle12 + angle13;
+ sum1223 = angle12 + angle23;
+ sum1323 = angle13 + angle23;
+
+ if (sum1213 < sum1223) {
+ if (sum1213 < sum1323) {
+ sum = sum1213;
+ junction.p2 = p1; junction.p1 = p2; junction.p3 = p3;
+ }else {
+ sum = sum1323;
+ junction.p2 = p3; junction.p1 = p1; junction.p3 = p2;
+ }
+ }else {
+ if (sum1223 < sum1323) {
+ sum = sum1223;
+ junction.p2 = p2; junction.p1 = p1; junction.p3 = p3;
+ }
+ else {
+ sum = sum1323;
+ junction.p2 = p3; junction.p1 = p1; junction.p3 = p2;
+ }
+ }
+
+ delta = sum - PI;
+ if (delta < 0)
+ delta = -delta;
+
+ if (delta < 0.001)
+ junction.name = 'tee';
+ else if (sum > PI)
+ junction.name = 'fork';
+ else
+ junction.name = 'arrow';
+}
+
+
+
+// Reverse the edges
+//(p reverse_edges
+// (stage ^value duplicate)
+// (line ^p1 <p1> ^p2 <p2>)
+// -->
+// (make edge ^p1 <p1> ^p2 <p2> ^joined false)
+// (make edge ^p1 <p2> ^p2 <p1> ^joined false)
+// (remove 2))
+rule reverse_edges {
+ when {
+ stage : Stage stage.value == 'DUPLICATE';
+ line : Line {p1:p1, p2:p2};
+ }
+ then {
+ emit("log", "Edge " + p1 + " " + p2 );
+ emit("log", "Edge " + p2 + " " + p1 );
+ assert( new Edge({p1 : p1, p2 : p2, joined : false}) );
+ assert( new Edge({p1 : p2, p2 : p1, joined : false}) );
+ retract( line );
+ }
+}
+// Reversing is done
+//(p done_reversing
+// (stage ^value duplicate)
+// - (line)
+// -->
+// (modify 1 ^value detect_junctions))
+rule done_reversing {
+ when{
+ stage : Stage stage.value == 'DUPLICATE';
+ not(l : Line);
+ }
+ then {
+ modify(stage, function(){ this.value = 'DETECT_JUNCTIONS'});
+ emit("log", "DETECT_JUNCTIONS" );
+ }
+}
+
+
+//(p make_3_junction
+// (stage ^value detect_junctions)
+// (edge ^p1 <base_point> ^p2 <p1> ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p2> <> <p1>} ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p3> <> <p1> <> <p2>} ^joined false)
+// -->
+// (make junction
+// ^type 3j
+// ^name (make_3_junction <base_point> <p1> <p2> <p3>)
+// ^base_point <base_point>
+// ^visited no)
+// (modify 2 ^type 3j ^joined true)
+// (modify 3 ^type 3j ^joined true)
+// (modify 4 ^type 3j ^joined true))
+
+rule make_3_junction {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ edge1 : Edge edge1.joined == false {p1 : basePoint, p2 : p1};
+ edge2 : Edge edge2.joined == false && edge2.p1 == basePoint && edge2.p2 != p1 {p2 : p2};
+ edge3 : Edge edge3.joined == false && edge3.p1 == basePoint && edge3.p2 != p1 && edge3.p2 != p2 {p2 : p3};
+ }
+ then {
+ var junction = new Junction({
+ basePoint : basePoint,
+ type : '3j',
+ visited : "no"
+ });
+ make3Junction(junction, basePoint, p1, p2, p3);
+ assert( junction );
+ emit("log", junction.toString( ) );
+ modify( edge1, function(){this.joined = true; this.type = '3j';});
+ modify( edge2, function(){this.joined = true; this.type = '3j';});
+ modify( edge3, function(){this.joined = true; this.type = '3j';});
+ }
+}
+
+//(p make_L
+// (stage ^value detect_junctions)
+// (edge ^p1 <base_point> ^p2 <p2> ^joined false)
+// (edge ^p1 <base_point> ^p2 {<p3> <> <p2>} ^joined false)
+// - (edge ^p1 <base_point> ^p2 {<> <p2> <> <p3>})
+// -->
+// (make junction
+// ^type 2j
+// ^name L
+// ^base_point <base_point>
+// ^p1 <p2>
+// ^p2 <p3>
+// ^visited no)
+// (modify 2 ^type 2j ^joined true)
+// (modify 3 ^type 2j ^joined true))
+
+rule make_L {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ edge1 : Edge edge1.joined == false {p1 : basePoint, p2 : p2};
+ edge2 : Edge edge2.p1 == basePoint && edge2.p2 != p2 && edge2.joined == false {p2 : p3};
+ not(e : Edge e.p1 == basePoint && e.p2 != p2 && e.p2 != p3 );
+ }
+ then {
+ var junction = new Junction({type : "2j", name : "L", basePoint : basePoint, p1 : p2, p2 : p3, visited : "no"} );
+ assert( junction );
+ emit("log", junction.toString() );
+ modify( edge1, function(){this.joined = true; this.type = "2j"});
+ modify( edge2, function(){this.joined = true; this.type = "2j"});
+ }
+}
+
+
+//(p done_detecting
+// (stage ^value detect_junctions)
+// - (edge ^joined false)
+// -->
+// (modify 1 ^value find_initial_boundary))
+rule done_detecting {
+ when {
+ stage : Stage stage.value == 'DETECT_JUNCTIONS';
+ not( e : Edge e.joined == false );
+ }
+ then {
+ modify(stage, function(){this.value = 'FIND_INITIAL_BOUNDARY' });
+ emit("log", "Stage: FIND_INITIAL_BOUNDARY" );
+ }
+}
+
+
+//(p initial_boundary_junction_L
+// (stage ^value find_initial_boundary)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// -(junction ^base_point > <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 1)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name B ^l_id 1)
+// (modify 1 ^value find_second_boundary))
+rule initial_boundary_junction_L {
+ when {
+ stage : Stage stage.value == 'FIND_INITIAL_BOUNDARY';
+ junction : Junction junction.type == '2j' {basePoint : basePoint, p1 : p1, p2 : p2};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ not(j : Junction j.type == '2j' && j.basePoint > basePoint );
+ }
+ then {
+ modify(junction, function(){ this.visited = "yes" });
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "1" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "B", labelId : "1" } ) );
+ modify(stage, function(){ this.value = 'FIND_SECOND_BOUNDARY' });
+ emit("log", "FIND_SECOND_BOUNDARY" );
+ }
+}
+
+//(p initial_boundary_junction_arrow
+// (stage ^value find_initial_boundary)
+// (junction ^type 3j ^name arrow ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p3>)
+// -(junction ^base_point > <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name + ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name B ^l_id 14)
+// (modify 1 ^value find_second_boundary))
+rule initial_boundary_junction_arrow {
+ when {
+ stage : Stage stage.value == 'FIND_INITIAL_BOUNDARY';
+ junction : Junction junction.type == '3j' && junction.name == 'arrow' {basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ edge1 : Edge edge1.p1 == basePoint && edge1.p2 == p1;
+ edge2 : Edge edge2.p1 == basePoint && edge2.p2 == p2;
+ edge3 : Edge edge3.p1 == basePoint && edge3.p2 == p3;
+ not(j : Junction j.basePoint > basePoint);
+ }
+ then {
+ modify( junction, function(){this.visited = "yes";});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "+", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : "B", labelId :"14" }) );
+ modify( stage, function() {this.value = 'FIND_SECOND_BOUNDARY';});
+ emit("log", "FIND_SECOND_BOUNDARY" );
+ }
+}
+
+
+//(p second_boundary_junction_L
+// (stage ^value find_second_boundary)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// -(junction ^base_point < <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 1)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name B ^l_id 1)
+// (modify 1 ^value labeling))
+
+rule second_boundary_junction_L {
+ when {
+ stage : Stage stage.value == 'FIND_SECOND_BOUNDARY';
+ junction : Junction junction.type == '2j' {basePoint : basePoint, p1 : p1, p2 : p2};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ not(j : Junction j.basePoint < basePoint);
+ }
+ then {
+ modify(junction, function(){ this.visited = "yes"});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "1" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "B", labelId : "1" }) );
+ modify(stage, function(){this.value = 'LABELING';});
+ emit("log", "LABELING" );
+ }
+}
+
+//(p second_boundary_junction_arrow
+// (stage ^value find_second_boundary)
+// (junction ^type 3j ^name arrow ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge ^p1 <bp> ^p2 <p1>)
+// (edge ^p1 <bp> ^p2 <p2>)
+// (edge ^p1 <bp> ^p2 <p3>)
+// -(junction ^base_point < <bp>)
+// -->
+// (modify 2 ^visited yes)
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name B ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name + ^l_id 14)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name B ^l_id 14)
+// (modify 1 ^value labeling))
+rule second_boundary_junction_arrow {
+ when {
+ stage : Stage stage.value == 'FIND_SECOND_BOUNDARY';
+ junction : Junction junction.type == '3j' && junction.name == 'arrow' {basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ e1 : Edge e1.p1 == basePoint && e1.p2 == p1;
+ e2 : Edge e2.p1 == basePoint && e2.p2 == p2;
+ e3 : Edge e3.p1 == basePoint && e3.p2 == p3;
+ not(j : Junction j.basePoint < basePoint);
+ }
+ then {
+ modify( junction, function(){this.visited = "yes"});
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : "B", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : "+", labelId : "14" }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : "B", labelId : "14" }) );
+ modify( stage, function(){this.value = 'LABELING'});
+ emit("log", "LABELING" );
+ }
+}
+
+
+//(p start_visit_3_junction
+// (stage ^value labeling)
+// (junction ^base_point <bp> ^type 3j ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited no)
+// -->
+// (modify 1 ^value visiting_3j)
+// (modify 2 ^visited now))
+
+rule start_visit_3_junction {
+ when {
+ stage : Stage stage.value == 'LABELING';
+ junction : Junction junction.type == '3j' && junction.visited == 'no'
+ }
+ then {
+ modify(stage, function(){this.value = 'VISITING_3J'});
+ modify(junction, function(){ this.visited = "now"});
+ emit("log", "VISITING_3J" );
+ }
+}
+
+
+//(p visit_3j_0
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_0 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_1
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_1 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint );
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_2
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_2 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_3
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// (edge_label ^p1 <p3> ^p2 <bp> ^l_name <n3>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_3 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint && el3.labelName == n3;
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_4
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_4 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p visit_3j_5
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_5 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_6
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_6 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not( el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+
+//(p visit_3j_7
+// (stage ^value visiting_3j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2> ^n3 <n3>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <p3> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p3> ^l_name <n3> ^l_id <id>))
+rule visit_3j_7 {
+ when {
+ s : Stage s.value == 'VISITING_3J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2, p3 : p3};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2, n3 : n3};
+ not( el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not( el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == p3 && el3.p2 == basePoint);
+ not( el4 : EdgeLabel el4.p1 == basePoint && el4.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p3 + " " + n3 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p3, labelName : n3, labelId : id }) );
+ }
+}
+
+//(p start_visit_2_junction
+// (stage ^value labeling)
+// (junction ^base_point <bp> ^type 2j ^p1 <p1> ^p2 <p2> ^visited no)
+// -->
+// (modify 1 ^value visiting_2j)
+// (modify 2 ^visited now))
+rule start_visit_2_junction {
+ when {
+ stage : Stage stage.value == 'LABELING';
+ junction : Junction junction.type == '2j' && junction.visited == 'no' {basePoint : basePoint, p1 : p1, p2 : p2};
+ }
+ then {
+ modify(junction, function(){ this.visited = "now";});
+ modify(stage, function(){ this.value = 'VISITING_2J';});
+ emit("log", "VISITING_2J" );
+ }
+}
+
+//(p visit_2j_0
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_0 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p visit_2j_1
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// (edge_label ^p1 <p2> ^p2 <bp> ^l_name <n2>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_1 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == n2;
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+
+//(p visit_2j_2
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// (edge_label ^p1 <p1> ^p2 <bp> ^l_name <n1>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_2 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint && el1.labelName == n1;
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not( el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p visit_2j_3
+// (stage ^value visiting_2j)
+// (junction ^name <n> ^base_point <bp> ^p1 <p1> ^p2 <p2> ^visited now)
+// (label ^name <n> ^id <id> ^n1 <n1> ^n2 <n2>)
+// -(edge_label ^p1 <p1> ^p2 <bp>)
+// -(edge_label ^p1 <p2> ^p2 <bp>)
+// -(edge_label ^p1 <bp> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// ; (write edge_label <bp> <p3> <n3> <id> (crlf))
+// (make edge_label ^p1 <bp> ^p2 <p1> ^l_name <n1> ^l_id <id>)
+// (make edge_label ^p1 <bp> ^p2 <p2> ^l_name <n2> ^l_id <id>))
+rule visit_2j_3 {
+ when {
+ s : Stage s.value == 'VISITING_2J';
+ j : Junction j.visited == 'now' {name : name, basePoint : basePoint, p1 : p1, p2 : p2};
+ l : Label l.name == name {id : id, n1 : n1, n2 : n2};
+ not(el1 : EdgeLabel el1.p1 == p1 && el1.p2 == basePoint);
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint);
+ not(el3 : EdgeLabel el3.p1 == basePoint && el3.labelId == id );
+ }
+ then {
+ emit("log", "EdgeLabel " + basePoint + " " + p1 + " " + n1 + " " + id );
+ emit("log", "EdgeLabel " + basePoint + " " + p2 + " " + n2 + " " + id );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p1, labelName : n1, labelId : id }) );
+ assert( new EdgeLabel({p1 : basePoint, p2 : p2, labelName : n2, labelId : id }) );
+ }
+}
+
+//(p end_visit
+// (stage ^value << visiting_3j visiting_2j >>)
+// (junction ^visited now)
+// -->
+// (modify 1 ^value marking))
+rule end_visit {
+ when {
+ stage : Stage stage.value == 'VISITING_2J' || stage.value == 'VISITING_3J';
+ junction : Junction junction.visited == 'now';
+ }
+ then {
+ modify(stage, function(){ this.value = 'MARKING';});
+ emit("log", "MARKING" );
+ }
+}
+
+//(p marking
+// (stage ^value marking)
+// (junction ^base_point <bp> ^visited now)
+// (edge ^p1 <p> ^p2 <bp>)
+// (junction ^base_point <p> ^visited yes)
+// -->
+// (modify 4 ^visited check))
+rule marking {
+ when {
+ s : Stage s.value == 'MARKING';
+ j : Junction j.visited == now {basePoint : basePoint};
+ e : Edge e.p2 == basePoint {p1 : p1};
+ junction : Junction junction.basePoint == p1 && junction.visited == 'yes';
+ }
+ then {
+ modify(junction, function(){ this.visited = "check"});
+ }
+}
+
+
+//(p stop_marking
+// (stage ^value marking)
+// (junction ^base_point <bp> ^visited now)
+// -->
+// (modify 2 ^visited yes))
+rule stop_marking {
+ when {
+ s : Stage s.value == 'MARKING';
+ junction : Junction junction.visited == 'now' {basePoint : basePoint};
+ }
+ then {
+ modify(junction, function(){this.visited = "yes"});
+ }
+}
+
+
+//(p start_checking
+// (stage ^value marking)
+// -->
+// (modify 1 ^value checking))
+//
+rule start_checking {
+ when {
+ stage : Stage stage.value == 'MARKING';
+ }
+ then {
+ modify(stage, function(){this.value = 'CHECKING';});
+ emit("log", "CHECKING" );
+ }
+}
+
+//(p checking
+// (stage ^value checking)
+// (junction ^base_point <bp> ^visited check)
+// (edge_label ^p1 <bp> ^p2 <p> ^l_name <n> ^l_id <id>)
+// (junction ^base_point <p> ^visited yes)
+// -(edge_label ^p1 <p> ^p2 <bp> ^l_name <n>)
+// -->
+// (modify 1 ^value remove_label)
+// (make illegal ^bp <bp> ^l_id <id>))
+rule checking {
+ when {
+ stage : Stage stage.value == 'CHECKING';
+ junction : Junction junction.visited == 'check' {basePoint : basePoint};
+ el1 : EdgeLabel el1.p1 == basePoint {p2 : p2, labelName : labelName, labelId : labelId};
+ j : Junction j.basePoint == p2 && j.visited == 'yes';
+ not(el2 : EdgeLabel el2.p1 == p2 && el2.p2 == basePoint && el2.labelName == labelName);
+ }
+ then {
+ modify(stage, function(){this.value = 'REMOVE_LABEL';});
+ emit("log", "REMOVE_LABEL" );
+ assert ( new Illegal({basePoint : basePoint, labelId : labelId}) );
+ }
+}
+
+//(p remove_label_3j
+// (stage ^value remove_label)
+// (illegal ^bp <bp> ^l_id <id>)
+// (junction ^type 3j ^base_point <bp> ^p1 <p1> ^p2 <p2> ^p3 <p3>)
+// (edge_label ^p1 <bp> ^p2 <p1> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p2> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p3> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <id> (crlf))
+// ; (write edge_label <bp> <p2> <id> (crlf))
+// (modify 1 ^value checking)
+// (remove 2)
+// (remove 4)
+// (remove 5)
+// (remove 6))
+rule remove_label_3j {
+ when {
+ stage : Stage stage.value == 'REMOVE_LABEL';
+ illegal : Illegal {basePoint : basePoint, labelId : labelId};
+ j : Junction j.type == '3j' && j.basePoint == basePoint {p1 : p1, p2 : p2, p3 : p3};
+ edgeLabel1 : EdgeLabel edgeLabel1.p1 == basePoint && edgeLabel1.p2 == p1 && edgeLabel1.labelId == labelId;
+ edgeLabel2 : EdgeLabel edgeLabel2.p1 == basePoint && edgeLabel2.p2 == p2 && edgeLabel2.labelId == labelId;
+ edgeLabel3 : EdgeLabel edgeLabel3.p1 == basePoint && edgeLabel3.p2 == p3 && edgeLabel3.labelId == labelId;
+ }
+ then {
+ modify( stage, function(){this.value = 'CHECKING';});
+ emit("log", "CHECKING" );
+ retract( illegal );
+ retract( edgeLabel1 );
+ retract( edgeLabel2 );
+ retract( edgeLabel3 );
+ }
+}
+
+//(p remove_edge_2j
+// (stage ^value remove_label)
+// (illegal ^bp <bp> ^l_id <id>)
+// (junction ^type 2j ^base_point <bp> ^p1 <p1> ^p2 <p2>)
+// (edge_label ^p1 <bp> ^p2 <p1> ^l_id <id>)
+// (edge_label ^p1 <bp> ^p2 <p2> ^l_id <id>)
+// -->
+// ; (write edge_label <bp> <p1> <n1> <id> (crlf))
+// ; (write edge_label <bp> <p2> <n2> <id> (crlf))
+// (modify 1 ^value checking)
+// (remove 2)
+// (remove 4)
+// (remove 5))
+rule remove_edge_2j {
+ when {
+ stage : Stage stage.value == 'REMOVE_LABEL';
+ illegal : Illegal {basePoint : basePoint, labelId : labelId};
+ j : Junction j.type == '2j' && j.basePoint == basePoint {p1 : p1, p2 : p2};
+ edgeLabel1 : EdgeLabel edgeLabel1.p1 == basePoint && edgeLabel1.p2 == p1 && edgeLabel1.labelId == labelId;
+ edgeLabel2 : EdgeLabel edgeLabel2.p1 == basePoint && edgeLabel2.p2 == p2 && edgeLabel2.labelId == labelId;