functionalscript 0.28.0 → 0.29.1
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/fs/ci/bun/module.f.js +1 -1
- package/fs/ci/node/module.f.js +3 -2
- package/fs/emergent_testing/module.f.js +4 -4
- package/fs/text/ascii/proof.f.d.ts +1 -0
- package/fs/text/ascii/proof.f.js +14 -2
- package/fs/types/prime_field/module.f.d.ts +7 -1
- package/fs/types/prime_field/module.f.js +10 -3
- package/fs/types/prime_field/proof.f.js +13 -0
- package/package.json +4 -4
package/fs/ci/bun/module.f.js
CHANGED
|
@@ -16,7 +16,7 @@ const installBun = installOnWindowsArm({
|
|
|
16
16
|
});
|
|
17
17
|
export const bunSteps = (extra) => (v, a) => clean([
|
|
18
18
|
installBun(v)(a),
|
|
19
|
-
test({ run: 'bun install' }),
|
|
19
|
+
test({ run: 'bun install --frozen-lockfile' }),
|
|
20
20
|
test({ run: 'bun test --timeout 20000' }),
|
|
21
21
|
...extra,
|
|
22
22
|
]);
|
package/fs/ci/node/module.f.js
CHANGED
|
@@ -34,10 +34,11 @@ export const nodeVersions = Object.fromEntries(node.others.map(v => [
|
|
|
34
34
|
`node${major(v)}`,
|
|
35
35
|
ubuntu(nodeSteps(v))
|
|
36
36
|
]));
|
|
37
|
+
const tsgoName = `@typescript/native-preview@${tsgo}`;
|
|
37
38
|
export const nodeMainSteps = (extra) => nodeTests(node.default)([
|
|
38
39
|
// TypeScript Preview
|
|
39
|
-
install({ run: `npm
|
|
40
|
-
test({ run:
|
|
40
|
+
install({ run: `npm cache add ${tsgoName}` }),
|
|
41
|
+
test({ run: `npx npm:${tsgoName}` }),
|
|
41
42
|
// extra
|
|
42
43
|
...extra,
|
|
43
44
|
]);
|
|
@@ -130,6 +130,8 @@ const runModule = ({ result, test }) => (k, v) => (ts) => {
|
|
|
130
130
|
.step(delta => pure(mergeState(ts, delta)));
|
|
131
131
|
};
|
|
132
132
|
const { entries } = Object;
|
|
133
|
+
const proofEntries = (moduleMap) => entries(moduleMap)
|
|
134
|
+
.flatMap(([k, v]) => v.proof !== undefined ? [[k, v.proof]] : []);
|
|
133
135
|
/**
|
|
134
136
|
* Runs all test modules in `moduleMap` whose names pass `isTest`, accumulates
|
|
135
137
|
* pass/fail/time via `reporter`, and returns an exit code (0 = all passed,
|
|
@@ -137,8 +139,7 @@ const { entries } = Object;
|
|
|
137
139
|
*/
|
|
138
140
|
export const runModuleMap = (reporter) => (moduleMap) => {
|
|
139
141
|
const { summary } = reporter;
|
|
140
|
-
const modules =
|
|
141
|
-
.flatMap(([k, v]) => v.proof !== undefined ? [[k, v.proof]] : []);
|
|
142
|
+
const modules = proofEntries(moduleMap);
|
|
142
143
|
return all(...modules.map(([k, v]) => runModule(reporter)(k, v)(zero)))
|
|
143
144
|
.step(m => pure(m.reduce(mergeState, zero)))
|
|
144
145
|
.step(ts => summary(ts.pass, ts.fail, ts.time)
|
|
@@ -155,8 +156,7 @@ export const testAll = (reporter) => options => loadModuleMap(options.env).step(
|
|
|
155
156
|
* `ctx`. Delegates to `registerModule` for each matching entry.
|
|
156
157
|
*/
|
|
157
158
|
const registerModuleMap = (ctx, star) => (moduleMap) => {
|
|
158
|
-
const modules =
|
|
159
|
-
.flatMap(([k, v]) => v.proof !== undefined ? [[k, v.proof]] : []);
|
|
159
|
+
const modules = proofEntries(moduleMap);
|
|
160
160
|
if (modules.length === 0) {
|
|
161
161
|
return pure(undefined);
|
|
162
162
|
}
|
package/fs/text/ascii/proof.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { range } from "./module.f.js";
|
|
1
|
+
import { one, range } from "./module.f.js";
|
|
2
2
|
import { stringify as jsonStringify } from "../../json/module.f.js";
|
|
3
3
|
import { sort } from "../../types/object/module.f.js";
|
|
4
4
|
const stringify = jsonStringify(sort);
|
|
@@ -8,5 +8,17 @@ export const proof = {
|
|
|
8
8
|
if (r !== '[65,65]') {
|
|
9
9
|
throw r;
|
|
10
10
|
}
|
|
11
|
-
}
|
|
11
|
+
},
|
|
12
|
+
oneThrowsOnEmpty: () => {
|
|
13
|
+
let threw = false;
|
|
14
|
+
try {
|
|
15
|
+
one('');
|
|
16
|
+
}
|
|
17
|
+
catch (_) {
|
|
18
|
+
threw = true;
|
|
19
|
+
}
|
|
20
|
+
if (!threw) {
|
|
21
|
+
throw 'expected throw';
|
|
22
|
+
}
|
|
23
|
+
},
|
|
12
24
|
};
|
|
@@ -26,7 +26,13 @@ export type PrimeField = {
|
|
|
26
26
|
readonly pow3: Unary;
|
|
27
27
|
/** Reduces an arbitrary `bigint` into `[0, p)`. */
|
|
28
28
|
readonly reduce: Unary;
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* `true` when `x` is a square modulo `p`, including `0`.
|
|
31
|
+
*
|
|
32
|
+
* Nonzero values are tested with Euler's criterion:
|
|
33
|
+
* `x^((p - 1) / 2) === 1 (mod p)`.
|
|
34
|
+
* For `p === 2n`, both field elements are squares.
|
|
35
|
+
*/
|
|
30
36
|
readonly quadRes: (x: bigint) => boolean;
|
|
31
37
|
};
|
|
32
38
|
/**
|
|
@@ -42,12 +42,19 @@ export const prime_field = (p) => {
|
|
|
42
42
|
const r = x % p;
|
|
43
43
|
return r < 0n ? add(p)(r) : r;
|
|
44
44
|
};
|
|
45
|
-
const
|
|
46
|
-
|
|
45
|
+
const max = p - 1n;
|
|
46
|
+
// Euler's exponent is `(p - 1) / 2`; use `max`, not `p`, so `p === 2n`
|
|
47
|
+
// gives exponent `0n` instead of `1n`.
|
|
48
|
+
// 0 is a square mod p; Euler's criterion needs a separate case because 0^e = 0.
|
|
49
|
+
const powHalf = pow(max >> 1n);
|
|
50
|
+
const quadRes = (x) => {
|
|
51
|
+
const v = reduce(x);
|
|
52
|
+
return v === 0n || powHalf(v) === 1n;
|
|
53
|
+
};
|
|
47
54
|
return {
|
|
48
55
|
p,
|
|
49
56
|
middle,
|
|
50
|
-
max
|
|
57
|
+
max,
|
|
51
58
|
neg: a => a === 0n ? 0n : p - a,
|
|
52
59
|
sub,
|
|
53
60
|
add,
|
|
@@ -153,12 +153,25 @@ export const proof = {
|
|
|
153
153
|
}
|
|
154
154
|
},
|
|
155
155
|
quadRes: () => {
|
|
156
|
+
if (!f.quadRes(0n)) {
|
|
157
|
+
throw 0n;
|
|
158
|
+
}
|
|
156
159
|
if (!f.quadRes(1n)) {
|
|
157
160
|
throw 1n;
|
|
158
161
|
}
|
|
162
|
+
if (!f.quadRes(p)) {
|
|
163
|
+
throw p;
|
|
164
|
+
}
|
|
159
165
|
if (f.quadRes(3n)) {
|
|
160
166
|
throw 3n;
|
|
161
167
|
}
|
|
168
|
+
const f2 = prime_field(2n);
|
|
169
|
+
if (!f2.quadRes(0n)) {
|
|
170
|
+
throw '0 mod 2';
|
|
171
|
+
}
|
|
172
|
+
if (!f2.quadRes(1n)) {
|
|
173
|
+
throw '1 mod 2';
|
|
174
|
+
}
|
|
162
175
|
},
|
|
163
176
|
modSqrt: () => {
|
|
164
177
|
const root = modSqrt(f);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"cov": "node --test --experimental-test-coverage --test-coverage-include=**/module.f.ts",
|
|
14
14
|
"start": "node ./fs/fjs/module.ts",
|
|
15
15
|
"ci-update": "node ./fs/fjs/module.ts ci",
|
|
16
|
-
"update": "npx npm-check-updates -u && npm install && deno install && npm run ci-update",
|
|
16
|
+
"update": "npx npm-check-updates -u && npm install && deno install && bun install && npm run ci-update",
|
|
17
17
|
"index-html": "node ./fs/fjs/module.ts r ./fs/website/module.f.ts",
|
|
18
|
-
"website": "npm run prepack &&npm run index-html"
|
|
18
|
+
"website": "npm run prepack && npm run index-html"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
21
|
+
"node": ">=22"
|
|
22
22
|
},
|
|
23
23
|
"bin": {
|
|
24
24
|
"fjs": "fs/fjs/module.js"
|