es6-fuzz 6.0.9 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +87 -0
- package/Readme.md +26 -10
- package/SECURITY.md +4 -5
- package/lib/curve/constant.d.ts +4 -3
- package/lib/curve/constant.d.ts.map +1 -1
- package/lib/curve/constant.js +5 -2
- package/lib/curve/constant.js.map +1 -1
- package/lib/curve/fuzzifier.d.ts +17 -0
- package/lib/curve/fuzzifier.d.ts.map +1 -0
- package/lib/curve/fuzzifier.js +3 -0
- package/lib/curve/fuzzifier.js.map +1 -0
- package/lib/curve/fuzzy-function.d.ts +2 -1
- package/lib/curve/fuzzy-function.d.ts.map +1 -1
- package/lib/curve/fuzzy-function.js +5 -2
- package/lib/curve/fuzzy-function.js.map +1 -1
- package/lib/curve/grade.d.ts +6 -0
- package/lib/curve/grade.d.ts.map +1 -1
- package/lib/curve/grade.js +27 -4
- package/lib/curve/grade.js.map +1 -1
- package/lib/curve/reverse-grade.d.ts +11 -1
- package/lib/curve/reverse-grade.d.ts.map +1 -1
- package/lib/curve/reverse-grade.js +37 -17
- package/lib/curve/reverse-grade.js.map +1 -1
- package/lib/curve/shape.d.ts +2 -1
- package/lib/curve/shape.d.ts.map +1 -1
- package/lib/curve/shape.js +20 -16
- package/lib/curve/shape.js.map +1 -1
- package/lib/curve/sigmoid.d.ts +10 -3
- package/lib/curve/sigmoid.d.ts.map +1 -1
- package/lib/curve/sigmoid.js +20 -2
- package/lib/curve/sigmoid.js.map +1 -1
- package/lib/curve/trapezoid.d.ts +8 -0
- package/lib/curve/trapezoid.d.ts.map +1 -1
- package/lib/curve/trapezoid.js +39 -19
- package/lib/curve/trapezoid.js.map +1 -1
- package/lib/curve/triangle.d.ts +7 -0
- package/lib/curve/triangle.d.ts.map +1 -1
- package/lib/curve/triangle.js +21 -2
- package/lib/curve/triangle.js.map +1 -1
- package/lib/index.d.ts +11 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +22 -0
- package/lib/index.js.map +1 -0
- package/lib/logic.d.ts +64 -5
- package/lib/logic.d.ts.map +1 -1
- package/lib/logic.js +118 -42
- package/lib/logic.js.map +1 -1
- package/lib/render-examples.js +92 -36
- package/lib/render-examples.js.map +1 -1
- package/lib/svg-renderer.d.ts.map +1 -1
- package/lib/svg-renderer.js +18 -9
- package/lib/svg-renderer.js.map +1 -1
- package/package.json +25 -16
package/lib/curve/sigmoid.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sigmoid.js","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;
|
|
1
|
+
{"version":3,"file":"sigmoid.js","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb;;;;;;GAMG;AACH,MAAa,OAAO;IACD,MAAM,CAAS;IACf,KAAK,CAAS;IAE/B;;;;;;;;;;OAUG;IACH,YAAY,SAAiB,CAAC,EAAE,QAAgB,CAAC;QAC/C,0EAA0E;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,gDAAgD,GAAG,MAAM,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,CAAC,+CAA+C,GAAG,KAAK,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,CAAS;QACf,4EAA4E;QAC5E,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACrB,mDAAmD;YACnD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,GAAG,CAAC,CAAC,kBAAkB;QAChC,CAAC;QACD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,CAAC;CACF;AA5CD,0BA4CC"}
|
package/lib/curve/trapezoid.d.ts
CHANGED
|
@@ -5,6 +5,14 @@ import { Shape } from './shape';
|
|
|
5
5
|
* new Trapezoid(0, 10, 15, 20)
|
|
6
6
|
*/
|
|
7
7
|
export declare class Trapezoid extends Shape {
|
|
8
|
+
/**
|
|
9
|
+
* Create a Trapezoid.
|
|
10
|
+
* @param {number} x0 - left foot (membership 0)
|
|
11
|
+
* @param {number} x1 - start of the plateau (membership 1)
|
|
12
|
+
* @param {number} x2 - end of the plateau (membership 1)
|
|
13
|
+
* @param {number} x3 - right foot (membership 0)
|
|
14
|
+
*/
|
|
15
|
+
constructor(x0: number, x1: number, x2: number, x3: number);
|
|
8
16
|
/**
|
|
9
17
|
* Fuzzify
|
|
10
18
|
* @param {number} val - Point on X axis
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trapezoid.d.ts","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAwC7B"}
|
|
1
|
+
{"version":3,"file":"trapezoid.d.ts","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC;;;;;;OAMG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAwC7B"}
|
package/lib/curve/trapezoid.js
CHANGED
|
@@ -8,6 +8,28 @@ const shape_1 = require("./shape");
|
|
|
8
8
|
* new Trapezoid(0, 10, 15, 20)
|
|
9
9
|
*/
|
|
10
10
|
class Trapezoid extends shape_1.Shape {
|
|
11
|
+
/**
|
|
12
|
+
* Create a Trapezoid.
|
|
13
|
+
* @param {number} x0 - left foot (membership 0)
|
|
14
|
+
* @param {number} x1 - start of the plateau (membership 1)
|
|
15
|
+
* @param {number} x2 - end of the plateau (membership 1)
|
|
16
|
+
* @param {number} x3 - right foot (membership 0)
|
|
17
|
+
*/
|
|
18
|
+
constructor(x0, x1, x2, x3) {
|
|
19
|
+
super(x0, x1, x2, x3);
|
|
20
|
+
// Reject out-of-order finite params. In particular an inverted plateau
|
|
21
|
+
// (x1 > x2) makes the plateau branch unsatisfiable, so the curve never
|
|
22
|
+
// reaches membership 1 and develops a discontinuity. NaN/Infinity, and the
|
|
23
|
+
// 3-argument form (x3 === undefined), are left untouched.
|
|
24
|
+
if (Number.isFinite(x0) &&
|
|
25
|
+
Number.isFinite(x1) &&
|
|
26
|
+
Number.isFinite(x2) &&
|
|
27
|
+
Number.isFinite(x3) &&
|
|
28
|
+
!(x0 <= x1 && x1 <= x2 && x2 <= x3)) {
|
|
29
|
+
throw Error('Trapezoid requires x0 <= x1 <= x2 <= x3 but got x0=' +
|
|
30
|
+
x0 + ', x1=' + x1 + ', x2=' + x2 + ', x3=' + x3);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
11
33
|
/**
|
|
12
34
|
* Fuzzify
|
|
13
35
|
* @param {number} val - Point on X axis
|
|
@@ -16,6 +38,10 @@ class Trapezoid extends shape_1.Shape {
|
|
|
16
38
|
fuzzify(val) {
|
|
17
39
|
let result = 0;
|
|
18
40
|
const x = val;
|
|
41
|
+
// NaN has no meaningful membership; treat it as outside the support (0)
|
|
42
|
+
// instead of letting it propagate through the edge arithmetic.
|
|
43
|
+
if (Number.isNaN(x))
|
|
44
|
+
return 0;
|
|
19
45
|
// Special case: all points equal (spike at single point)
|
|
20
46
|
if (this.x0 === this.x1 && this.x1 === this.x2 && this.x2 === this.x3) {
|
|
21
47
|
return x === this.x0 ? 1 : 0;
|
|
@@ -30,32 +56,26 @@ class Trapezoid extends shape_1.Shape {
|
|
|
30
56
|
return 0;
|
|
31
57
|
return 0;
|
|
32
58
|
}
|
|
33
|
-
if (x <= this.
|
|
59
|
+
if (x >= this.x1 && x <= this.x2) {
|
|
60
|
+
// Plateau, corners included. When a single edge is vertical (x0===x1 or
|
|
61
|
+
// x2===x3) the corner must read 1 — consistent with the rectangle case
|
|
62
|
+
// above and with Triangle. Evaluating the plateau before the x<=x0 / x>=x3
|
|
63
|
+
// zero guards is what makes those corners correct instead of dropping to 0.
|
|
64
|
+
result = 1;
|
|
65
|
+
}
|
|
66
|
+
else if (x <= this.x0) {
|
|
34
67
|
result = 0;
|
|
35
68
|
}
|
|
36
69
|
else if (x >= this.x3) {
|
|
37
70
|
result = 0;
|
|
38
71
|
}
|
|
39
|
-
else if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
else if ((x > this.x0) && (x < this.x1)) {
|
|
43
|
-
// Handle case where x0 = x1 (vertical left edge)
|
|
44
|
-
if (this.x1 === this.x0) {
|
|
45
|
-
result = 1;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
result = (x / (this.x1 - this.x0)) - (this.x0 / (this.x1 - this.x0));
|
|
49
|
-
}
|
|
72
|
+
else if (x > this.x0 && x < this.x1) {
|
|
73
|
+
// Rising edge — only reached when x0 < x1, so the divisor is never 0.
|
|
74
|
+
result = x / (this.x1 - this.x0) - this.x0 / (this.x1 - this.x0);
|
|
50
75
|
}
|
|
51
76
|
else {
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
result = 1;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
result = (-x / (this.x3 - this.x2)) + (this.x3 / (this.x3 - this.x2));
|
|
58
|
-
}
|
|
77
|
+
// Falling edge — only reached when x2 < x3, so the divisor is never 0.
|
|
78
|
+
result = -x / (this.x3 - this.x2) + this.x3 / (this.x3 - this.x2);
|
|
59
79
|
}
|
|
60
80
|
return result;
|
|
61
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trapezoid.js","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,SAAU,SAAQ,aAAK;IAClC;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,yDAAyD;QACzD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACtE,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,4CAA4C;QAC5C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"trapezoid.js","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"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"}
|
package/lib/curve/triangle.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ import { Shape } from './shape';
|
|
|
5
5
|
* new Triangle(0, 10, 20)
|
|
6
6
|
*/
|
|
7
7
|
export declare class Triangle extends Shape {
|
|
8
|
+
/**
|
|
9
|
+
* Create a Triangle.
|
|
10
|
+
* @param {number} x0 - left base point
|
|
11
|
+
* @param {number} x1 - peak
|
|
12
|
+
* @param {number} x2 - right base point
|
|
13
|
+
*/
|
|
14
|
+
constructor(x0: number, x1: number, x2: number);
|
|
8
15
|
/**
|
|
9
16
|
* Fuzzify
|
|
10
17
|
* @param {number} x - Point on X axis
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triangle.d.ts","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAwC3B"}
|
|
1
|
+
{"version":3,"file":"triangle.d.ts","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC;;;;;OAKG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAiB9C;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAwC3B"}
|
package/lib/curve/triangle.js
CHANGED
|
@@ -8,6 +8,25 @@ const shape_1 = require("./shape");
|
|
|
8
8
|
* new Triangle(0, 10, 20)
|
|
9
9
|
*/
|
|
10
10
|
class Triangle extends shape_1.Shape {
|
|
11
|
+
/**
|
|
12
|
+
* Create a Triangle.
|
|
13
|
+
* @param {number} x0 - left base point
|
|
14
|
+
* @param {number} x1 - peak
|
|
15
|
+
* @param {number} x2 - right base point
|
|
16
|
+
*/
|
|
17
|
+
constructor(x0, x1, x2) {
|
|
18
|
+
super(x0, x1, x2, x2);
|
|
19
|
+
// Reject out-of-order finite params. With x0 > x1 or x1 > x2 the branch
|
|
20
|
+
// guards make whole edges unreachable, so the peak (x1) never reaches 1 and
|
|
21
|
+
// the curve is discontinuous or collapses to the empty set. NaN/Infinity are
|
|
22
|
+
// left untouched (handled at fuzzify time, relied on for open-ended shapes).
|
|
23
|
+
if (Number.isFinite(x0) &&
|
|
24
|
+
Number.isFinite(x1) &&
|
|
25
|
+
Number.isFinite(x2) &&
|
|
26
|
+
!(x0 <= x1 && x1 <= x2)) {
|
|
27
|
+
throw Error('Triangle requires x0 <= x1 <= x2 but got x0=' + x0 + ', x1=' + x1 + ', x2=' + x2);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
11
30
|
/**
|
|
12
31
|
* Fuzzify
|
|
13
32
|
* @param {number} x - Point on X axis
|
|
@@ -50,10 +69,10 @@ class Triangle extends shape_1.Shape {
|
|
|
50
69
|
else if (x >= this.x2) {
|
|
51
70
|
result = 0;
|
|
52
71
|
}
|
|
53
|
-
else if (
|
|
72
|
+
else if (x > this.x0 && x <= this.x1) {
|
|
54
73
|
result = (x - this.x0) / (this.x1 - this.x0);
|
|
55
74
|
}
|
|
56
|
-
else if (
|
|
75
|
+
else if (x > this.x1 && x < this.x2) {
|
|
57
76
|
result = (this.x2 - x) / (this.x2 - this.x1);
|
|
58
77
|
}
|
|
59
78
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triangle.js","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,QAAS,SAAQ,aAAK;IACjC;;;;OAIG;IACH,OAAO,CAAC,CAAS;QACf,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,yDAAyD;QACzD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/C,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,6CAA6C;QAC7C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;gBAC/B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"triangle.js","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Logic } from './logic';
|
|
2
|
+
export { Shape } from './curve/shape';
|
|
3
|
+
export { Fuzzifier } from './curve/fuzzifier';
|
|
4
|
+
export { Grade } from './curve/grade';
|
|
5
|
+
export { ReverseGrade } from './curve/reverse-grade';
|
|
6
|
+
export { Triangle } from './curve/triangle';
|
|
7
|
+
export { Trapezoid } from './curve/trapezoid';
|
|
8
|
+
export { Constant } from './curve/constant';
|
|
9
|
+
export { FuzzyFunction } from './curve/fuzzy-function';
|
|
10
|
+
export { Sigmoid } from './curve/sigmoid';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Sigmoid = exports.FuzzyFunction = exports.Constant = exports.Trapezoid = exports.Triangle = exports.ReverseGrade = exports.Grade = exports.Shape = exports.Logic = void 0;
|
|
4
|
+
var logic_1 = require("./logic");
|
|
5
|
+
Object.defineProperty(exports, "Logic", { enumerable: true, get: function () { return logic_1.Logic; } });
|
|
6
|
+
var shape_1 = require("./curve/shape");
|
|
7
|
+
Object.defineProperty(exports, "Shape", { enumerable: true, get: function () { return shape_1.Shape; } });
|
|
8
|
+
var grade_1 = require("./curve/grade");
|
|
9
|
+
Object.defineProperty(exports, "Grade", { enumerable: true, get: function () { return grade_1.Grade; } });
|
|
10
|
+
var reverse_grade_1 = require("./curve/reverse-grade");
|
|
11
|
+
Object.defineProperty(exports, "ReverseGrade", { enumerable: true, get: function () { return reverse_grade_1.ReverseGrade; } });
|
|
12
|
+
var triangle_1 = require("./curve/triangle");
|
|
13
|
+
Object.defineProperty(exports, "Triangle", { enumerable: true, get: function () { return triangle_1.Triangle; } });
|
|
14
|
+
var trapezoid_1 = require("./curve/trapezoid");
|
|
15
|
+
Object.defineProperty(exports, "Trapezoid", { enumerable: true, get: function () { return trapezoid_1.Trapezoid; } });
|
|
16
|
+
var constant_1 = require("./curve/constant");
|
|
17
|
+
Object.defineProperty(exports, "Constant", { enumerable: true, get: function () { return constant_1.Constant; } });
|
|
18
|
+
var fuzzy_function_1 = require("./curve/fuzzy-function");
|
|
19
|
+
Object.defineProperty(exports, "FuzzyFunction", { enumerable: true, get: function () { return fuzzy_function_1.FuzzyFunction; } });
|
|
20
|
+
var sigmoid_1 = require("./curve/sigmoid");
|
|
21
|
+
Object.defineProperty(exports, "Sigmoid", { enumerable: true, get: function () { return sigmoid_1.Sigmoid; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,uCAAsC;AAA7B,8FAAA,KAAK,OAAA;AAEd,uCAAsC;AAA7B,8FAAA,KAAK,OAAA;AACd,uDAAqD;AAA5C,6GAAA,YAAY,OAAA;AACrB,6CAA4C;AAAnC,oGAAA,QAAQ,OAAA;AACjB,+CAA8C;AAArC,sGAAA,SAAS,OAAA;AAClB,6CAA4C;AAAnC,oGAAA,QAAQ,OAAA;AACjB,yDAAuD;AAA9C,+GAAA,aAAa,OAAA;AACtB,2CAA0C;AAAjC,kGAAA,OAAO,OAAA"}
|
package/lib/logic.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Shape } from './curve/shape';
|
|
2
|
+
import { Fuzzifier } from './curve/fuzzifier';
|
|
2
3
|
import { Grade } from './curve/grade';
|
|
3
4
|
import { ReverseGrade } from './curve/reverse-grade';
|
|
4
5
|
import { Triangle } from './curve/triangle';
|
|
@@ -10,6 +11,11 @@ import { Sigmoid } from './curve/sigmoid';
|
|
|
10
11
|
export declare class Logic {
|
|
11
12
|
private initCalled;
|
|
12
13
|
private rules;
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Redundant with the package's named exports. Import the shape
|
|
16
|
+
* classes directly instead, e.g. `import { Triangle } from 'es6-fuzz'`.
|
|
17
|
+
* Kept for backwards compatibility and slated for removal in the next major.
|
|
18
|
+
*/
|
|
13
19
|
c: {
|
|
14
20
|
Shape: typeof Shape;
|
|
15
21
|
Grade: typeof Grade;
|
|
@@ -23,17 +29,70 @@ export declare class Logic {
|
|
|
23
29
|
constructor();
|
|
24
30
|
private checkInitCalled;
|
|
25
31
|
private checkOutputName;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Registers a rule and marks the logic chain as started; one `init` call must
|
|
34
|
+
* precede {@link and}, {@link or}, {@link not} or {@link defuzzify}. It may be
|
|
35
|
+
* called more than once — a later `init` just adds another rule that starts a
|
|
36
|
+
* fresh membership, which is the same effect as {@link or}.
|
|
37
|
+
*
|
|
38
|
+
* Rule composition is sequential and order-dependent: at {@link defuzzify}
|
|
39
|
+
* time each rule's membership is folded into a single value that is carried
|
|
40
|
+
* to the next rule (see {@link and}). `init` and `or` start a fresh value
|
|
41
|
+
* from the rule's own shape; `and` narrows it; `not` inverts it.
|
|
42
|
+
*
|
|
43
|
+
* @param output Output label, letters only (`/^[a-z]+$/i`), must be unique.
|
|
44
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
45
|
+
*/
|
|
46
|
+
init(output: string, shape: Fuzzifier): this;
|
|
47
|
+
/**
|
|
48
|
+
* Narrows the carried membership with `min(previous, shape(value))`
|
|
49
|
+
* (the standard fuzzy-AND / T-norm). Because `previous` is whatever the
|
|
50
|
+
* immediately preceding rule produced, `and` is order-dependent — it
|
|
51
|
+
* composes against the prior rule in the chain, not a grouped rule set.
|
|
52
|
+
*
|
|
53
|
+
* @param output Output label, letters only, must be unique.
|
|
54
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
55
|
+
*/
|
|
56
|
+
and(output: string, shape: Fuzzifier): this;
|
|
57
|
+
/**
|
|
58
|
+
* Starts a fresh membership from this rule's own shape value, ignoring the
|
|
59
|
+
* value carried from previous rules (fuzzy-OR / max is applied implicitly by
|
|
60
|
+
* {@link defuzzify} picking the single highest membership across all rules).
|
|
61
|
+
*
|
|
62
|
+
* @param output Output label, letters only, must be unique.
|
|
63
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
64
|
+
*/
|
|
65
|
+
or(output: string, shape: Fuzzifier): this;
|
|
66
|
+
/**
|
|
67
|
+
* Inverts this rule's shape value: `1 - shape(value)` (fuzzy-NOT /
|
|
68
|
+
* complement). Like {@link or}, it does not depend on the carried value.
|
|
69
|
+
*
|
|
70
|
+
* @param output Output label, letters only, must be unique.
|
|
71
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
72
|
+
*/
|
|
73
|
+
not(output: string, shape: Fuzzifier): this;
|
|
74
|
+
/**
|
|
75
|
+
* Evaluates every rule for `value` and returns the result.
|
|
76
|
+
*
|
|
77
|
+
* Note on terminology: this performs **max-membership classification**, not
|
|
78
|
+
* centroid / center-of-gravity defuzzification. It returns the *label* of the
|
|
79
|
+
* rule with the highest membership (`defuzzified`) together with that
|
|
80
|
+
* membership degree (`fuzzified`) — it does not compute a crisp output
|
|
81
|
+
* number. On ties the earliest rule wins (strict greater-than).
|
|
82
|
+
*
|
|
83
|
+
* @param value Crisp input fed to every rule's shape.
|
|
84
|
+
* @param as Optional namespace prefix for {@link DefuzzifyResult.boonJsInputs}
|
|
85
|
+
* keys, e.g. `'heat'` yields `heat.cold`. Useful when merging the inputs of
|
|
86
|
+
* several `Logic` instances for boon-js evaluation.
|
|
87
|
+
* @example logic.defuzzify(10)
|
|
88
|
+
*/
|
|
30
89
|
defuzzify(value: number, as?: string): Logic.DefuzzifyResult;
|
|
31
90
|
}
|
|
32
91
|
export declare namespace Logic {
|
|
33
92
|
type RuleType = 'init' | 'and' | 'or' | 'not';
|
|
34
93
|
interface Rule {
|
|
35
94
|
output: string;
|
|
36
|
-
shape:
|
|
95
|
+
shape: Fuzzifier;
|
|
37
96
|
type: RuleType;
|
|
38
97
|
fuzzy?: number;
|
|
39
98
|
}
|
package/lib/logic.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA8B1C,qCAAqC;AACrC,qBAAa,KAAK;IAChB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,KAAK,CAAc;IAE3B;;;;OAIG;IACI,CAAC,EAAE;QACR,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,YAAY,EAAE,OAAO,YAAY,CAAC;QAClC,SAAS,EAAE,OAAO,SAAS,CAAC;QAC5B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,aAAa,EAAE,OAAO,aAAa,CAAC;QACpC,OAAO,EAAE,OAAO,OAAO,CAAC;KACzB,CAAC;;IAeF,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,eAAe;IAevB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ5C;;;;;;;;OAQG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;OAOG;IACH,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ1C;;;;;;OAMG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,eAAe;CAkE7D;AAED,yBAAiB,KAAK,CAAC;IACrB,KAAY,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IAErD,UAAiB,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IAED,UAAiB,eAAe;QAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,MAAM,CAAC;QAClB,QAAQ,IAAI,MAAM,CAAC;KACpB;CACF"}
|
package/lib/logic.js
CHANGED
|
@@ -13,21 +13,34 @@ const TYPE_INIT = 'init';
|
|
|
13
13
|
const TYPE_AND = 'and';
|
|
14
14
|
const TYPE_OR = 'or';
|
|
15
15
|
const TYPE_NOT = 'not';
|
|
16
|
+
/**
|
|
17
|
+
* Maps a rule to the membership degree of its output, given the membership
|
|
18
|
+
* carried along the chain so far (`prev`) and this rule's own shape value
|
|
19
|
+
* (`raw`). The winning output is then the one with the highest membership.
|
|
20
|
+
*/
|
|
16
21
|
const ruleEngine = {
|
|
17
|
-
|
|
18
|
-
return
|
|
22
|
+
init(_prev, raw) {
|
|
23
|
+
return raw;
|
|
19
24
|
},
|
|
20
|
-
or(
|
|
21
|
-
return
|
|
25
|
+
or(_prev, raw) {
|
|
26
|
+
return raw;
|
|
27
|
+
},
|
|
28
|
+
and(prev, raw) {
|
|
29
|
+
return Math.min(prev, raw);
|
|
30
|
+
},
|
|
31
|
+
not(_prev, raw) {
|
|
32
|
+
return 1 - raw;
|
|
22
33
|
},
|
|
23
|
-
not(a, b = null, value) {
|
|
24
|
-
return 1 - a.fuzzify(value);
|
|
25
|
-
}
|
|
26
34
|
};
|
|
27
35
|
/** Class helping with FuzzyLogic. */
|
|
28
36
|
class Logic {
|
|
29
37
|
initCalled = false;
|
|
30
38
|
rules = [];
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Redundant with the package's named exports. Import the shape
|
|
41
|
+
* classes directly instead, e.g. `import { Triangle } from 'es6-fuzz'`.
|
|
42
|
+
* Kept for backwards compatibility and slated for removal in the next major.
|
|
43
|
+
*/
|
|
31
44
|
c;
|
|
32
45
|
constructor() {
|
|
33
46
|
this.c = {
|
|
@@ -38,7 +51,7 @@ class Logic {
|
|
|
38
51
|
Triangle: triangle_1.Triangle,
|
|
39
52
|
Constant: constant_1.Constant,
|
|
40
53
|
FuzzyFunction: fuzzy_function_1.FuzzyFunction,
|
|
41
|
-
Sigmoid: sigmoid_1.Sigmoid
|
|
54
|
+
Sigmoid: sigmoid_1.Sigmoid,
|
|
42
55
|
};
|
|
43
56
|
}
|
|
44
57
|
checkInitCalled() {
|
|
@@ -47,11 +60,31 @@ class Logic {
|
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
62
|
checkOutputName(name) {
|
|
63
|
+
// ASCII letters only — the keys end up as boon-js identifiers, which are
|
|
64
|
+
// not Unicode-aware, so non-ASCII letters (e.g. "ÜberHeiss") are rejected
|
|
65
|
+
// by design rather than silently producing an unusable boon-js input.
|
|
50
66
|
const reg = /^[a-z]+$/i;
|
|
51
67
|
if (!reg.test(name)) {
|
|
52
|
-
throw Error('Output names can only be strings without space, without numbers and without special chars');
|
|
68
|
+
throw Error('Output names can only be strings without space, without numbers and without special chars (ASCII letters a-z only)');
|
|
69
|
+
}
|
|
70
|
+
if (this.rules.some((rule) => rule.output === name)) {
|
|
71
|
+
throw Error('Output name "' + name + '" is already in use');
|
|
53
72
|
}
|
|
54
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Registers a rule and marks the logic chain as started; one `init` call must
|
|
76
|
+
* precede {@link and}, {@link or}, {@link not} or {@link defuzzify}. It may be
|
|
77
|
+
* called more than once — a later `init` just adds another rule that starts a
|
|
78
|
+
* fresh membership, which is the same effect as {@link or}.
|
|
79
|
+
*
|
|
80
|
+
* Rule composition is sequential and order-dependent: at {@link defuzzify}
|
|
81
|
+
* time each rule's membership is folded into a single value that is carried
|
|
82
|
+
* to the next rule (see {@link and}). `init` and `or` start a fresh value
|
|
83
|
+
* from the rule's own shape; `and` narrows it; `not` inverts it.
|
|
84
|
+
*
|
|
85
|
+
* @param output Output label, letters only (`/^[a-z]+$/i`), must be unique.
|
|
86
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
87
|
+
*/
|
|
55
88
|
init(output, shape) {
|
|
56
89
|
this.checkOutputName(output);
|
|
57
90
|
this.initCalled = true;
|
|
@@ -59,79 +92,122 @@ class Logic {
|
|
|
59
92
|
this.rules.push({ output, shape, type });
|
|
60
93
|
return this;
|
|
61
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Narrows the carried membership with `min(previous, shape(value))`
|
|
97
|
+
* (the standard fuzzy-AND / T-norm). Because `previous` is whatever the
|
|
98
|
+
* immediately preceding rule produced, `and` is order-dependent — it
|
|
99
|
+
* composes against the prior rule in the chain, not a grouped rule set.
|
|
100
|
+
*
|
|
101
|
+
* @param output Output label, letters only, must be unique.
|
|
102
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
103
|
+
*/
|
|
62
104
|
and(output, shape) {
|
|
63
|
-
this.checkOutputName(output);
|
|
64
105
|
this.checkInitCalled();
|
|
106
|
+
this.checkOutputName(output);
|
|
65
107
|
const type = TYPE_AND;
|
|
66
108
|
this.rules.push({ output, shape, type });
|
|
67
109
|
return this;
|
|
68
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Starts a fresh membership from this rule's own shape value, ignoring the
|
|
113
|
+
* value carried from previous rules (fuzzy-OR / max is applied implicitly by
|
|
114
|
+
* {@link defuzzify} picking the single highest membership across all rules).
|
|
115
|
+
*
|
|
116
|
+
* @param output Output label, letters only, must be unique.
|
|
117
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
118
|
+
*/
|
|
69
119
|
or(output, shape) {
|
|
70
|
-
this.checkOutputName(output);
|
|
71
120
|
this.checkInitCalled();
|
|
121
|
+
this.checkOutputName(output);
|
|
72
122
|
const type = TYPE_OR;
|
|
73
123
|
this.rules.push({ output, shape, type });
|
|
74
124
|
return this;
|
|
75
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Inverts this rule's shape value: `1 - shape(value)` (fuzzy-NOT /
|
|
128
|
+
* complement). Like {@link or}, it does not depend on the carried value.
|
|
129
|
+
*
|
|
130
|
+
* @param output Output label, letters only, must be unique.
|
|
131
|
+
* @param shape Fuzzifier mapping a crisp input to a membership degree 0..1.
|
|
132
|
+
*/
|
|
76
133
|
not(output, shape) {
|
|
77
|
-
this.checkOutputName(output);
|
|
78
134
|
this.checkInitCalled();
|
|
135
|
+
this.checkOutputName(output);
|
|
79
136
|
const type = TYPE_NOT;
|
|
80
137
|
this.rules.push({ output, shape, type });
|
|
81
138
|
return this;
|
|
82
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Evaluates every rule for `value` and returns the result.
|
|
142
|
+
*
|
|
143
|
+
* Note on terminology: this performs **max-membership classification**, not
|
|
144
|
+
* centroid / center-of-gravity defuzzification. It returns the *label* of the
|
|
145
|
+
* rule with the highest membership (`defuzzified`) together with that
|
|
146
|
+
* membership degree (`fuzzified`) — it does not compute a crisp output
|
|
147
|
+
* number. On ties the earliest rule wins (strict greater-than).
|
|
148
|
+
*
|
|
149
|
+
* @param value Crisp input fed to every rule's shape.
|
|
150
|
+
* @param as Optional namespace prefix for {@link DefuzzifyResult.boonJsInputs}
|
|
151
|
+
* keys, e.g. `'heat'` yields `heat.cold`. Useful when merging the inputs of
|
|
152
|
+
* several `Logic` instances for boon-js evaluation.
|
|
153
|
+
* @example logic.defuzzify(10)
|
|
154
|
+
*/
|
|
83
155
|
defuzzify(value, as) {
|
|
84
156
|
this.checkInitCalled();
|
|
85
157
|
let defuzzified = 'none';
|
|
86
158
|
let fuzzified = 0;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
159
|
+
// Seed at 0, not -Infinity: a rule only wins with membership strictly above
|
|
160
|
+
// 0. When no rule fires (every membership is 0) there is genuinely no winner,
|
|
161
|
+
// so 'none' is returned instead of the first rule being reported with a
|
|
162
|
+
// membership of 0 (which also kept its boonJsInputs entry wrongly true).
|
|
163
|
+
let best = 0;
|
|
164
|
+
// membership carried along the chain, used by AND to narrow the result
|
|
165
|
+
let running = 0;
|
|
166
|
+
// Defend against fuzzifiers that violate the 0..1 contract: clamp the raw
|
|
167
|
+
// value (and map NaN to 0) before composing. Otherwise a rogue shape — or
|
|
168
|
+
// `not` computing 1 - raw on it — could make the winner's fuzzified value
|
|
169
|
+
// fall outside 0..1.
|
|
170
|
+
const clamp = (v) => Number.isNaN(v) ? 0 : Math.min(1, Math.max(0, v));
|
|
171
|
+
// Evaluate into fresh rule copies so the engine's internal state is never
|
|
172
|
+
// mutated or handed out to the caller.
|
|
173
|
+
const rules = this.rules.map((rule) => {
|
|
174
|
+
const raw = clamp(rule.shape.fuzzify(value));
|
|
175
|
+
const membership = ruleEngine[rule.type](running, raw);
|
|
176
|
+
running = membership;
|
|
177
|
+
// max-membership defuzzification: highest membership wins, ties keep
|
|
178
|
+
// the earliest rule (strict greater-than)
|
|
179
|
+
if (membership > best) {
|
|
180
|
+
best = membership;
|
|
106
181
|
defuzzified = rule.output;
|
|
107
|
-
fuzzified =
|
|
108
|
-
// if there is no shape, like for example for a NOT keep the last one
|
|
109
|
-
lastShape = rule.shape || lastShape;
|
|
182
|
+
fuzzified = membership;
|
|
110
183
|
}
|
|
184
|
+
return { ...rule, fuzzy: membership };
|
|
111
185
|
});
|
|
112
186
|
let namePrefix = '';
|
|
113
|
-
if (as
|
|
187
|
+
if (as) {
|
|
188
|
+
// Validate the namespace prefix with the same rule as output names, so it
|
|
189
|
+
// can't inject spaces, dots or other characters into the boonJsInputs keys
|
|
190
|
+
// (which are meant to be valid boon-js identifiers).
|
|
191
|
+
if (typeof as !== 'string' || !/^[a-z]+$/i.test(as)) {
|
|
192
|
+
throw Error('The "as" namespace prefix can only be letters without space, without numbers and without special chars');
|
|
193
|
+
}
|
|
114
194
|
namePrefix = as + '.';
|
|
115
195
|
}
|
|
116
196
|
const boonJsInputs = {};
|
|
117
|
-
|
|
197
|
+
rules.forEach((rule) => {
|
|
118
198
|
boonJsInputs[`${namePrefix}${rule.output}`] = rule.output === defuzzified;
|
|
119
199
|
});
|
|
120
|
-
/**
|
|
121
|
-
*
|
|
122
|
-
* @example fuzzy.defuzzify(10)
|
|
123
|
-
*/
|
|
124
200
|
return {
|
|
125
201
|
boonJsInputs,
|
|
126
202
|
fuzzified: fuzzified,
|
|
127
203
|
defuzzified: defuzzified,
|
|
128
|
-
rules
|
|
204
|
+
rules,
|
|
129
205
|
valueOf() {
|
|
130
206
|
return fuzzified;
|
|
131
207
|
},
|
|
132
208
|
toString() {
|
|
133
209
|
return defuzzified;
|
|
134
|
-
}
|
|
210
|
+
},
|
|
135
211
|
};
|
|
136
212
|
}
|
|
137
213
|
}
|
package/lib/logic.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"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"}
|