functionalscript 0.30.0 → 0.31.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/fs/asn.1/module.f.js +18 -22
- package/fs/asn.1/proof.f.d.ts +5 -0
- package/fs/asn.1/proof.f.js +38 -2
- package/fs/base64/module.f.d.ts +9 -0
- package/fs/base64/module.f.js +60 -0
- package/fs/base64/proof.f.d.ts +11 -0
- package/fs/base64/proof.f.js +117 -0
- package/fs/base_n/module.f.d.ts +44 -0
- package/fs/base_n/module.f.js +54 -0
- package/fs/base_n/proof.f.d.ts +10 -0
- package/fs/base_n/proof.f.js +86 -0
- package/fs/bnf/data/module.f.d.ts +4 -9
- package/fs/bnf/data/module.f.js +4 -3
- package/fs/bnf/module.f.d.ts +3 -4
- package/fs/bnf/module.f.js +3 -2
- package/fs/bnf/proof.f.d.ts +9 -0
- package/fs/bnf/proof.f.js +98 -1
- package/fs/cas/mcp/module.f.d.ts +40 -0
- package/fs/cas/mcp/module.f.js +223 -0
- package/fs/cas/mcp/proof.f.d.ts +30 -0
- package/fs/cas/mcp/proof.f.js +310 -0
- package/fs/cas/module.f.d.ts +9 -3
- package/fs/cas/module.f.js +104 -69
- package/fs/cas/proof.f.d.ts +2 -0
- package/fs/cas/proof.f.js +30 -1
- package/fs/cbase32/module.f.d.ts +1 -1
- package/fs/cbase32/module.f.js +19 -40
- package/fs/cbase32/proof.f.d.ts +1 -0
- package/fs/cbase32/proof.f.js +15 -0
- package/fs/ci/config/module.f.d.ts +6 -6
- package/fs/ci/config/module.f.js +6 -6
- package/fs/ci/deno/module.f.js +2 -2
- package/fs/ci/module.f.d.ts +5 -0
- package/fs/ci/module.f.js +2 -3
- package/fs/ci/proof.f.d.ts +1 -0
- package/fs/ci/proof.f.js +9 -3
- package/fs/cli/module.f.d.ts +3 -1
- package/fs/cli/module.f.js +22 -12
- package/fs/cli/proof.f.d.ts +5 -0
- package/fs/cli/proof.f.js +76 -0
- package/fs/crypto/hmac/proof.f.d.ts +1 -0
- package/fs/crypto/hmac/proof.f.js +8 -0
- package/fs/crypto/secp/proof.f.d.ts +1 -0
- package/fs/crypto/secp/proof.f.js +10 -0
- package/fs/crypto/sign/module.f.js +1 -4
- package/fs/dev/module.f.d.ts +5 -3
- package/fs/dev/module.f.js +13 -2
- package/fs/dev/package_json/proof.f.d.ts +1 -0
- package/fs/dev/package_json/proof.f.js +5 -0
- package/fs/dev/proof.f.d.ts +1 -0
- package/fs/dev/proof.f.js +12 -1
- package/fs/djs/ast/module.f.d.ts +1 -1
- package/fs/djs/ast/proof.f.d.ts +5 -0
- package/fs/djs/ast/proof.f.js +17 -0
- package/fs/djs/module.f.d.ts +1 -1
- package/fs/djs/module.f.js +2 -3
- package/fs/djs/serializer/module.f.js +24 -11
- package/fs/djs/transpiler/module.f.js +3 -4
- package/fs/effects/memory/module.f.d.ts +37 -0
- package/fs/effects/memory/module.f.js +24 -0
- package/fs/effects/memory/proof.f.d.ts +6 -0
- package/fs/effects/memory/proof.f.js +64 -0
- package/fs/effects/mock/module.f.d.ts +7 -2
- package/fs/effects/mock/module.f.js +12 -8
- package/fs/effects/module.d.ts +1 -1
- package/fs/effects/module.f.d.ts +41 -0
- package/fs/effects/module.f.js +25 -0
- package/fs/effects/module.js +6 -7
- package/fs/effects/node/memory/module.d.ts +20 -0
- package/fs/effects/node/memory/module.js +44 -0
- package/fs/effects/node/memory/proof.d.ts +10 -0
- package/fs/effects/node/memory/proof.js +35 -0
- package/fs/effects/node/module.d.ts +1 -1
- package/fs/effects/node/module.f.d.ts +54 -8
- package/fs/effects/node/module.f.js +55 -4
- package/fs/effects/node/module.js +166 -135
- package/fs/effects/node/proof.f.d.ts +10 -0
- package/fs/effects/node/proof.f.js +88 -21
- package/fs/effects/node/virtual/module.f.d.ts +6 -0
- package/fs/effects/node/virtual/module.f.js +48 -16
- package/fs/effects/node/virtual/proof.f.d.ts +17 -0
- package/fs/effects/node/virtual/proof.f.js +79 -0
- package/fs/effects/proof.f.d.ts +5 -0
- package/fs/effects/proof.f.js +54 -34
- package/fs/emergent_testing/module.f.d.ts +6 -1
- package/fs/emergent_testing/module.f.js +8 -3
- package/fs/emergent_testing/proof.f.d.ts +11 -0
- package/fs/emergent_testing/proof.f.js +52 -16
- package/fs/fjs/module.f.js +2 -2
- package/fs/fjs/proof.f.d.ts +8 -0
- package/fs/fjs/proof.f.js +39 -0
- package/fs/fsc/module.f.d.ts +5 -0
- package/fs/fsc/module.f.js +17 -27
- package/fs/fsc/proof.f.d.ts +8 -0
- package/fs/fsc/proof.f.js +48 -2
- package/fs/fsm/module.f.d.ts +2 -3
- package/fs/fsm/module.f.js +1 -1
- package/fs/html/module.f.d.ts +2 -3
- package/fs/html/module.f.js +7 -6
- package/fs/html/proof.f.d.ts +1 -0
- package/fs/html/proof.f.js +7 -0
- package/fs/js/tokenizer/module.f.js +1 -1
- package/fs/js/tokenizer/proof.f.js +7 -0
- package/fs/json/module.f.d.ts +9 -2
- package/fs/json/module.f.js +9 -7
- package/fs/json/parser/module.f.js +4 -6
- package/fs/json/parser/proof.f.js +19 -10
- package/fs/json/proof.f.d.ts +2 -1
- package/fs/json/proof.f.js +33 -6
- package/fs/json/rpc/module.f.d.ts +5 -0
- package/fs/json/rpc/module.f.js +16 -11
- package/fs/json/schema/module.f.d.ts +15 -14
- package/fs/json/schema/proof.f.d.ts +3 -0
- package/fs/json/schema/proof.f.js +16 -1
- package/fs/mcp/module.f.d.ts +103 -5
- package/fs/mcp/module.f.js +139 -2
- package/fs/mcp/proof.f.d.ts +34 -0
- package/fs/mcp/proof.f.js +207 -0
- package/fs/mcp/stdio/module.f.d.ts +39 -0
- package/fs/mcp/stdio/module.f.js +54 -0
- package/fs/mcp/stdio/proof.f.d.ts +10 -0
- package/fs/mcp/stdio/proof.f.js +92 -0
- package/fs/mime/module.f.d.ts +39 -0
- package/fs/mime/module.f.js +78 -0
- package/fs/mime/proof.f.d.ts +15 -0
- package/fs/mime/proof.f.js +30 -0
- package/fs/path/module.f.d.ts +8 -0
- package/fs/path/module.f.js +10 -3
- package/fs/path/proof.f.d.ts +1 -0
- package/fs/path/proof.f.js +40 -2
- package/fs/text/sgr/proof.f.js +30 -2
- package/fs/text/utf8/module.f.d.ts +7 -0
- package/fs/text/utf8/module.f.js +85 -31
- package/fs/text/utf8/proof.f.d.ts +1 -0
- package/fs/text/utf8/proof.f.js +60 -1
- package/fs/types/bigfloat/module.f.d.ts +3 -0
- package/fs/types/bigfloat/module.f.js +30 -31
- package/fs/types/bigint/module.f.d.ts +24 -2
- package/fs/types/bigint/module.f.js +30 -2
- package/fs/types/bigint/proof.f.d.ts +7 -0
- package/fs/types/bigint/proof.f.js +47 -16
- package/fs/types/bit_vec/module.f.d.ts +18 -0
- package/fs/types/bit_vec/module.f.js +18 -0
- package/fs/types/bit_vec/proof.f.d.ts +1 -0
- package/fs/types/bit_vec/proof.f.js +13 -1
- package/fs/types/function/operator/proof.f.d.ts +2 -0
- package/fs/types/function/operator/proof.f.js +20 -2
- package/fs/types/list/module.f.js +1 -4
- package/fs/types/list/proof.f.d.ts +1 -1
- package/fs/types/list/proof.f.js +14 -6
- package/fs/types/map/proof.f.d.ts +1 -0
- package/fs/types/map/proof.f.js +10 -1
- package/fs/types/nibble_set/module.f.d.ts +13 -0
- package/fs/types/nibble_set/module.f.js +16 -0
- package/fs/types/object/module.f.d.ts +12 -8
- package/fs/types/object/module.f.js +9 -2
- package/fs/types/object/proof.f.d.ts +14 -0
- package/fs/types/object/proof.f.js +4 -0
- package/fs/types/ordered_map/proof.f.d.ts +1 -0
- package/fs/types/ordered_map/proof.f.js +39 -79
- package/fs/types/phantom/module.f.d.ts +22 -0
- package/fs/types/phantom/module.f.js +11 -0
- package/fs/types/prime_field/proof.f.d.ts +7 -0
- package/fs/types/prime_field/proof.f.js +63 -122
- package/fs/types/rtti/common/module.f.d.ts +4 -4
- package/fs/types/rtti/common/module.f.js +1 -1
- package/fs/types/rtti/module.f.d.ts +2 -3
- package/fs/types/rtti/parse/module.f.js +0 -1
- package/fs/types/rtti/ts/module.f.d.ts +26 -32
- package/fs/types/rtti/ts/module.f.js +2 -2
- package/fs/types/rtti/ts/proof.f.js +3 -3
- package/fs/types/rtti/validate/module.f.js +0 -1
- package/fs/types/sorted_list/module.f.d.ts +6 -0
- package/fs/types/sorted_list/module.f.js +11 -0
- package/fs/types/sorted_set/module.f.js +2 -8
- package/fs/types/ts/module.f.d.ts +1 -1
- package/fs/types/ts/module.f.js +3 -1
- package/fs/types/ts/proof.f.js +3 -2
- package/fs/website/proof.f.d.ts +1 -0
- package/fs/website/proof.f.js +8 -1
- package/package.json +3 -3
|
@@ -56,10 +56,7 @@ export const toArray = (list) => {
|
|
|
56
56
|
};
|
|
57
57
|
const apply = (f) => (input) => () => {
|
|
58
58
|
const n = next(input);
|
|
59
|
-
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
return f(n);
|
|
59
|
+
return n === null ? null : f(n);
|
|
63
60
|
};
|
|
64
61
|
const flatStep = ({ first, tail }) => concat(first)(flat(tail));
|
|
65
62
|
export const flat = apply(flatStep);
|
package/fs/types/list/proof.f.js
CHANGED
|
@@ -9,12 +9,20 @@ const stringifyTest = () => {
|
|
|
9
9
|
throw s;
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
|
-
const cycleTest =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
12
|
+
const cycleTest = [
|
|
13
|
+
() => {
|
|
14
|
+
const x = str(toArray(take(10)(cycle([1, 2, 3]))));
|
|
15
|
+
if (x !== '[1,2,3,1,2,3,1,2,3,1]') {
|
|
16
|
+
throw x;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
() => {
|
|
20
|
+
const x = str(toArray(cycle([])));
|
|
21
|
+
if (x !== '[]') {
|
|
22
|
+
throw x;
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
];
|
|
18
26
|
const countdownTest = () => {
|
|
19
27
|
const result = str(countdown(10));
|
|
20
28
|
if (result !== '[9,8,7,6,5,4,3,2,1,0]') {
|
package/fs/types/map/proof.f.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mapSet, mapDelete } from "./module.f.js";
|
|
2
|
+
import { assertEq } from "../../asserts/module.f.js";
|
|
2
3
|
export const proof = {
|
|
3
4
|
set: () => {
|
|
4
5
|
const map = mapSet(new Map(), 'a', 'b');
|
|
@@ -17,5 +18,13 @@ export const proof = {
|
|
|
17
18
|
if (map.size !== 0) {
|
|
18
19
|
throw 'error';
|
|
19
20
|
}
|
|
20
|
-
}
|
|
21
|
+
},
|
|
22
|
+
deleteOneOfMany: () => {
|
|
23
|
+
const m0 = mapSet(new Map(), 'a', 1);
|
|
24
|
+
const m1 = mapSet(m0, 'b', 2);
|
|
25
|
+
const result = mapDelete(m1, 'a');
|
|
26
|
+
assertEq(result.get('b'), 2);
|
|
27
|
+
assertEq(result.get('a'), undefined);
|
|
28
|
+
assertEq(result.size, 1);
|
|
29
|
+
},
|
|
21
30
|
};
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Nibble-set operations for compact 4-bit membership tracking.
|
|
3
3
|
*
|
|
4
|
+
* A set of nibbles (values `0..15`) stored as a 16-bit mask in a plain
|
|
5
|
+
* `number`. It implements the same bitmask-as-set algebra as
|
|
6
|
+
* {@link ../byte_set/module.f.ts | `byte_set`}, which tracks all 256 byte
|
|
7
|
+
* values in a `bigint`.
|
|
8
|
+
*
|
|
9
|
+
* **Prefer `byte_set`.** Its 256-value universe covers the common cases and
|
|
10
|
+
* it is the set type used across the codebase. Use `nibble_set` only when
|
|
11
|
+
* the set has to be serialized into JSON: a `NibbleSet` is a `number`, which
|
|
12
|
+
* round-trips through `JSON.stringify`/`JSON.parse` as-is, while a
|
|
13
|
+
* `ByteSet` is a `bigint`, which `JSON.stringify` cannot serialize.
|
|
14
|
+
*
|
|
4
15
|
* @module
|
|
5
16
|
*/
|
|
17
|
+
/** A set of nibbles as a 16-bit mask. JSON-serializable. */
|
|
6
18
|
export type NibbleSet = number;
|
|
19
|
+
/** A 4-bit value, `0..15`. */
|
|
7
20
|
export type Nibble = number;
|
|
8
21
|
export declare const empty = 0;
|
|
9
22
|
export declare const universe = 65535;
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nibble-set operations for compact 4-bit membership tracking.
|
|
3
|
+
*
|
|
4
|
+
* A set of nibbles (values `0..15`) stored as a 16-bit mask in a plain
|
|
5
|
+
* `number`. It implements the same bitmask-as-set algebra as
|
|
6
|
+
* {@link ../byte_set/module.f.ts | `byte_set`}, which tracks all 256 byte
|
|
7
|
+
* values in a `bigint`.
|
|
8
|
+
*
|
|
9
|
+
* **Prefer `byte_set`.** Its 256-value universe covers the common cases and
|
|
10
|
+
* it is the set type used across the codebase. Use `nibble_set` only when
|
|
11
|
+
* the set has to be serialized into JSON: a `NibbleSet` is a `number`, which
|
|
12
|
+
* round-trips through `JSON.stringify`/`JSON.parse` as-is, while a
|
|
13
|
+
* `ByteSet` is a `bigint`, which `JSON.stringify` cannot serialize.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
1
17
|
export const empty = 0;
|
|
2
18
|
export const universe = 0xFFFF;
|
|
3
19
|
const one = n => 1 << n;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { type List } from '../list/module.f.ts';
|
|
2
|
+
import { type Nullable } from '../nullable/module.f.ts';
|
|
2
3
|
import { type OrderedMap } from '../ordered_map/module.f.ts';
|
|
3
|
-
export type Map<T> =
|
|
4
|
-
readonly [k in string]: T;
|
|
5
|
-
};
|
|
4
|
+
export type Map<T> = StringMap<string, T>;
|
|
6
5
|
export type Entry<T> = readonly [string, T];
|
|
7
|
-
export declare const at: (name: string) => <T>(object: Map<T>) => T
|
|
6
|
+
export declare const at: (name: string) => <T>(object: Map<T>) => Nullable<Exclude<T, undefined>>;
|
|
8
7
|
export declare const sort: <T>(e: List<Entry<T>>) => List<Entry<T>>;
|
|
9
8
|
export declare const fromEntries: <T>(e: List<Entry<T>>) => Map<T>;
|
|
10
9
|
export declare const fromMap: <T>(m: OrderedMap<T>) => Map<T>;
|
|
@@ -15,7 +14,7 @@ export declare const fromMap: <T>(m: OrderedMap<T>) => Map<T>;
|
|
|
15
14
|
* https://stackoverflow.com/questions/57571664/typescript-type-for-an-object-with-only-one-key-no-union-type-allowed-as-a-key
|
|
16
15
|
*/
|
|
17
16
|
export type OneKey<K extends string, V> = {
|
|
18
|
-
[P in K]: (
|
|
17
|
+
[P in K]: (StringMap<P, V> & Partial<StringMap<Exclude<K, P>, never>>) extends infer O ? {
|
|
19
18
|
[Q in keyof O]: O[Q];
|
|
20
19
|
} : never;
|
|
21
20
|
}[K];
|
|
@@ -25,8 +24,13 @@ export type OneKey<K extends string, V> = {
|
|
|
25
24
|
export type NotUnion<T, U = T> = T extends unknown ? [
|
|
26
25
|
U
|
|
27
26
|
] extends [T] ? T : never : never;
|
|
28
|
-
export type SingleProperty<T extends
|
|
27
|
+
export type SingleProperty<T extends StringMap<string, never>> = keyof T extends NotUnion<keyof T> ? T : never;
|
|
29
28
|
export declare const isObject: (value: unknown) => value is { readonly [k in string]: unknown; };
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
/** Returns only the defined (non-undefined) values of a partial record. */
|
|
30
|
+
export declare const definedValues: <T>(map: StringMap<string, Exclude<T, undefined>>) => readonly Exclude<T, undefined>[];
|
|
31
|
+
export type StringMap<K extends string, T> = string extends K ? {
|
|
32
|
+
readonly [k in string]?: T;
|
|
33
|
+
} : {
|
|
34
|
+
readonly [k in K]: T;
|
|
32
35
|
};
|
|
36
|
+
export declare const definedEntries: <T>(cmd: StringMap<string, Exclude<T, undefined>>) => readonly (readonly [string, Exclude<T, undefined>])[];
|
|
@@ -7,11 +7,18 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { isArray } from "../array/module.f.js";
|
|
9
9
|
import { iterable } from "../list/module.f.js";
|
|
10
|
-
import { fromUndefined
|
|
10
|
+
import { fromUndefined } from "../nullable/module.f.js";
|
|
11
11
|
import { entries as mapEntries, fromEntries as mapFromEntries } from "../ordered_map/module.f.js";
|
|
12
12
|
const { getOwnPropertyDescriptor, fromEntries: objectFromEntries } = Object;
|
|
13
|
-
export const at = name => object =>
|
|
13
|
+
export const at = name => object => {
|
|
14
|
+
const d = getOwnPropertyDescriptor(object, name);
|
|
15
|
+
return d === undefined ? null : fromUndefined(d.value);
|
|
16
|
+
};
|
|
14
17
|
export const sort = e => mapEntries(mapFromEntries(e));
|
|
15
18
|
export const fromEntries = e => objectFromEntries(iterable(e));
|
|
16
19
|
export const fromMap = m => fromEntries(mapEntries(m));
|
|
17
20
|
export const isObject = (value) => typeof value === 'object' && !isArray(value) && value !== null;
|
|
21
|
+
const { values, entries } = Object;
|
|
22
|
+
/** Returns only the defined (non-undefined) values of a partial record. */
|
|
23
|
+
export const definedValues = (map) => values(map).filter(v => v !== undefined);
|
|
24
|
+
export const definedEntries = (cmd) => entries(cmd).flatMap(([a, b]) => b === undefined ? [] : [[a, b]]);
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
+
import type { StringMap } from './module.f.ts';
|
|
2
|
+
type E<A, B> = A extends B ? B extends A ? true : false : false;
|
|
3
|
+
type _InfiniteIsOptional = E<StringMap<string, bigint>, {
|
|
4
|
+
readonly [k in string]?: bigint;
|
|
5
|
+
}>;
|
|
6
|
+
type _FiniteIsRequired = E<StringMap<'a' | 'b', bigint>, {
|
|
7
|
+
readonly a: bigint;
|
|
8
|
+
readonly b: bigint;
|
|
9
|
+
}>;
|
|
1
10
|
export declare const proof: {
|
|
11
|
+
stringMap: {
|
|
12
|
+
infiniteIsOptional: _InfiniteIsOptional;
|
|
13
|
+
finiteIsRequired: _FiniteIsRequired;
|
|
14
|
+
};
|
|
2
15
|
ctor: () => void;
|
|
3
16
|
property: () => void;
|
|
4
17
|
};
|
|
18
|
+
export {};
|
|
@@ -1,101 +1,61 @@
|
|
|
1
|
-
import { at, setReplace, setReduce, empty, entries, remove } from "./module.f.js";
|
|
1
|
+
import { at, setReplace, setReduce, empty, entries, remove, fromEntries } from "./module.f.js";
|
|
2
2
|
import { toArray } from "../list/module.f.js";
|
|
3
|
+
import { assertEq } from "../../asserts/module.f.js";
|
|
3
4
|
export const proof = {
|
|
4
5
|
main: [
|
|
5
6
|
() => {
|
|
6
7
|
let m = setReplace('a')(1)(null);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
if (at('b')(m) !== null) {
|
|
11
|
-
throw 'error';
|
|
12
|
-
}
|
|
8
|
+
assertEq(at('a')(m), 1);
|
|
9
|
+
assertEq(at('b')(m), null);
|
|
13
10
|
m = setReplace('b')(2)(m);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (at('b')(m) !== 2) {
|
|
18
|
-
throw 'error';
|
|
19
|
-
}
|
|
20
|
-
if (at('c')(m) !== null) {
|
|
21
|
-
throw 'error';
|
|
22
|
-
}
|
|
11
|
+
assertEq(at('a')(m), 1);
|
|
12
|
+
assertEq(at('b')(m), 2);
|
|
13
|
+
assertEq(at('c')(m), null);
|
|
23
14
|
m = setReplace('z')(3)(m);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throw 'error';
|
|
29
|
-
}
|
|
30
|
-
if (at('z')(m) !== 3) {
|
|
31
|
-
throw 'error';
|
|
32
|
-
}
|
|
33
|
-
if (at('')(m) !== null) {
|
|
34
|
-
throw 'error';
|
|
35
|
-
}
|
|
15
|
+
assertEq(at('a')(m), 1);
|
|
16
|
+
assertEq(at('b')(m), 2);
|
|
17
|
+
assertEq(at('z')(m), 3);
|
|
18
|
+
assertEq(at('')(m), null);
|
|
36
19
|
m = setReplace('')(4)(m);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
if (at('z')(m) !== 3) {
|
|
44
|
-
throw 'error';
|
|
45
|
-
}
|
|
46
|
-
if (at('')(m) !== 4) {
|
|
47
|
-
throw 'error';
|
|
48
|
-
}
|
|
49
|
-
if (at('Hello world!')(m) !== null) {
|
|
50
|
-
throw 'error';
|
|
51
|
-
}
|
|
20
|
+
assertEq(at('a')(m), 1);
|
|
21
|
+
assertEq(at('b')(m), 2);
|
|
22
|
+
assertEq(at('z')(m), 3);
|
|
23
|
+
assertEq(at('')(m), 4);
|
|
24
|
+
assertEq(at('Hello world!')(m), null);
|
|
52
25
|
m = setReplace('Hello world!')(42)(m);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (at('z')(m) !== 3) {
|
|
60
|
-
throw 'error';
|
|
61
|
-
}
|
|
62
|
-
if (at('')(m) !== 4) {
|
|
63
|
-
throw 'error';
|
|
64
|
-
}
|
|
65
|
-
if (at('Hello world!')(m) !== 42) {
|
|
66
|
-
throw 'error';
|
|
67
|
-
}
|
|
68
|
-
if (at('x')(m) !== null) {
|
|
69
|
-
throw 'error';
|
|
70
|
-
}
|
|
26
|
+
assertEq(at('a')(m), 1);
|
|
27
|
+
assertEq(at('b')(m), 2);
|
|
28
|
+
assertEq(at('z')(m), 3);
|
|
29
|
+
assertEq(at('')(m), 4);
|
|
30
|
+
assertEq(at('Hello world!')(m), 42);
|
|
31
|
+
assertEq(at('x')(m), null);
|
|
71
32
|
// console.log(Array.from(m.entries()))
|
|
72
33
|
m = remove('Hello world!')(m);
|
|
73
|
-
|
|
74
|
-
throw m;
|
|
75
|
-
}
|
|
34
|
+
assertEq(at('Hello world!')(m), null);
|
|
76
35
|
m = setReduce((a) => (b) => a + b)('a')(43)(m);
|
|
77
|
-
|
|
78
|
-
throw 'error';
|
|
79
|
-
}
|
|
36
|
+
assertEq(at('a')(m), 44);
|
|
80
37
|
},
|
|
81
38
|
() => {
|
|
82
39
|
let m = setReplace('x')(12)(null);
|
|
83
40
|
m = setReplace('y')(44)(m);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (at('y')(m) !== 44) {
|
|
88
|
-
throw 'error';
|
|
89
|
-
}
|
|
90
|
-
if (at('a')(m) !== null) {
|
|
91
|
-
throw 'error';
|
|
92
|
-
}
|
|
41
|
+
assertEq(at('x')(m), 12);
|
|
42
|
+
assertEq(at('y')(m), 44);
|
|
43
|
+
assertEq(at('a')(m), null);
|
|
93
44
|
const e = toArray(entries(m));
|
|
94
|
-
|
|
95
|
-
throw 'error';
|
|
96
|
-
}
|
|
45
|
+
assertEq(e.length, 2);
|
|
97
46
|
},
|
|
98
47
|
],
|
|
48
|
+
fromEntries: () => {
|
|
49
|
+
const list = [['a', 1], ['b', 2], ['c', 3]];
|
|
50
|
+
const m = fromEntries(list);
|
|
51
|
+
assertEq(at('a')(m), 1);
|
|
52
|
+
assertEq(at('b')(m), 2);
|
|
53
|
+
assertEq(at('c')(m), 3);
|
|
54
|
+
assertEq(at('d')(m), null);
|
|
55
|
+
// duplicate key: last one wins
|
|
56
|
+
const m2 = fromEntries([['x', 10], ['x', 20]]);
|
|
57
|
+
assertEq(at('x')(m2), 20);
|
|
58
|
+
},
|
|
99
59
|
stress: () => {
|
|
100
60
|
let m = empty;
|
|
101
61
|
for (let i = 0; i < 100_000; ++i) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phantom type — attaches a compile-time type annotation `T` to `S` with zero
|
|
3
|
+
* runtime representation, analogous to Rust's `PhantomData<T>`.
|
|
4
|
+
*
|
|
5
|
+
* The phantom field uses a unique symbol key so it is excluded from string index
|
|
6
|
+
* signatures (`{ readonly [K in string]: ... }`), making `Phantom<S, T>` valid
|
|
7
|
+
* for any `S` regardless of its index signature constraints.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
declare const phantomKey: unique symbol;
|
|
12
|
+
export type { phantomKey };
|
|
13
|
+
/**
|
|
14
|
+
* Intersects `S` with a phantom field carrying type `T`.
|
|
15
|
+
*
|
|
16
|
+
* The field is optional (`?`) so it never needs to be present at runtime.
|
|
17
|
+
* Use `phantomKey` to read the phantom type back out via a conditional type:
|
|
18
|
+
* `S extends Phantom<unknown, infer T> ? T : never`.
|
|
19
|
+
*/
|
|
20
|
+
export type Phantom<S, T> = S & {
|
|
21
|
+
readonly [phantomKey]?: T;
|
|
22
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phantom type — attaches a compile-time type annotation `T` to `S` with zero
|
|
3
|
+
* runtime representation, analogous to Rust's `PhantomData<T>`.
|
|
4
|
+
*
|
|
5
|
+
* The phantom field uses a unique symbol key so it is excluded from string index
|
|
6
|
+
* signatures (`{ readonly [K in string]: ... }`), making `Phantom<S, T>` valid
|
|
7
|
+
* for any `S` regardless of its index signature constraints.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const proof: {
|
|
2
|
+
throw: {
|
|
3
|
+
reciprocal_zero: () => bigint;
|
|
4
|
+
sqrt_bad_prime: () => (a: bigint) => bigint | null;
|
|
5
|
+
};
|
|
2
6
|
prime_field_test: () => {
|
|
3
7
|
neg: () => void;
|
|
4
8
|
sub: () => void;
|
|
@@ -11,5 +15,8 @@ export declare const proof: {
|
|
|
11
15
|
reduce: () => void;
|
|
12
16
|
quadRes: () => void;
|
|
13
17
|
modSqrt: () => void;
|
|
18
|
+
div: () => void;
|
|
19
|
+
pow3: () => void;
|
|
20
|
+
abs: () => void;
|
|
14
21
|
};
|
|
15
22
|
};
|
|
@@ -1,121 +1,69 @@
|
|
|
1
1
|
import { modSqrt, prime_field, sqrt } from "./module.f.js";
|
|
2
|
+
import { assert, assertEq } from "../../asserts/module.f.js";
|
|
2
3
|
export const proof = {
|
|
4
|
+
throw: {
|
|
5
|
+
reciprocal_zero: () => prime_field(7n).reciprocal(0n),
|
|
6
|
+
sqrt_bad_prime: () => sqrt(prime_field(5n)),
|
|
7
|
+
},
|
|
3
8
|
prime_field_test: () => {
|
|
4
9
|
const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
5
10
|
const f = prime_field(p);
|
|
6
11
|
const sqrt_f = sqrt(f);
|
|
7
12
|
return {
|
|
8
13
|
neg: () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
if (f.neg(1n) !== p - 1n) {
|
|
13
|
-
throw '-1';
|
|
14
|
-
}
|
|
14
|
+
assertEq(f.neg(0n), 0n);
|
|
15
|
+
assertEq(f.neg(1n), p - 1n);
|
|
15
16
|
},
|
|
16
17
|
sub: () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
if (f.sub(11n)(14n) !== p - 3n) {
|
|
21
|
-
throw '11 - 14';
|
|
22
|
-
}
|
|
18
|
+
assertEq(f.sub(10n)(4n), 6n);
|
|
19
|
+
assertEq(f.sub(11n)(14n), p - 3n);
|
|
23
20
|
},
|
|
24
21
|
add: () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
if (f.add(77n)(f.neg(12n)) !== 65n) {
|
|
29
|
-
throw '77 + (-12)';
|
|
30
|
-
}
|
|
22
|
+
assertEq(f.add(13n)(24n), 37n);
|
|
23
|
+
assertEq(f.add(77n)(f.neg(12n)), 65n);
|
|
31
24
|
},
|
|
32
25
|
mul: () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
if (f.mul(304n)(f.neg(1n)) !== f.neg(304n)) {
|
|
40
|
-
throw '304 * -1';
|
|
41
|
-
}
|
|
42
|
-
if (f.mul(f.neg(507n))(609n) !== f.neg(308763n)) {
|
|
43
|
-
throw '-507 * 609';
|
|
44
|
-
}
|
|
45
|
-
if (f.mul(f.neg(713n))(f.neg(825n)) !== 588225n) {
|
|
46
|
-
throw '-713 * -825';
|
|
47
|
-
}
|
|
26
|
+
assertEq(f.mul(100n)(0n), 0n);
|
|
27
|
+
assertEq(f.mul(101n)(205n), 20705n);
|
|
28
|
+
assertEq(f.mul(304n)(f.neg(1n)), f.neg(304n));
|
|
29
|
+
assertEq(f.mul(f.neg(507n))(609n), f.neg(308763n));
|
|
30
|
+
assertEq(f.mul(f.neg(713n))(f.neg(825n)), 588225n);
|
|
48
31
|
},
|
|
49
32
|
reciprocal: () => {
|
|
50
33
|
let i = 1n;
|
|
51
34
|
while (i < 10000n) {
|
|
52
|
-
|
|
53
|
-
if (f.mul(x)(i) !== 1n) {
|
|
54
|
-
throw i;
|
|
55
|
-
}
|
|
35
|
+
assertEq(f.mul(f.reciprocal(i))(i), 1n);
|
|
56
36
|
++i;
|
|
57
37
|
}
|
|
58
38
|
},
|
|
59
39
|
pow: () => {
|
|
60
40
|
const test = a => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
if (f.pow(1n)(a) !== a) {
|
|
65
|
-
throw '**1';
|
|
66
|
-
}
|
|
41
|
+
assertEq(f.pow(0n)(a), 1n);
|
|
42
|
+
assertEq(f.pow(1n)(a), a);
|
|
67
43
|
// https://en.wikipedia.org/wiki/Fermat%27s_little_theorem
|
|
68
44
|
// a^(p-1) % p = 1
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (f.pow(f.sub(f.max)(1n))(a) !== f.reciprocal(a)) {
|
|
73
|
-
throw '**(max-1)';
|
|
74
|
-
}
|
|
75
|
-
if (f.pow(f.max)(a) !== 1n) {
|
|
76
|
-
throw '**max';
|
|
77
|
-
}
|
|
45
|
+
assertEq(f.abs(f.pow(f.middle)(a)), 1n);
|
|
46
|
+
assertEq(f.pow(f.sub(f.max)(1n))(a), f.reciprocal(a));
|
|
47
|
+
assertEq(f.pow(f.max)(a), 1n);
|
|
78
48
|
};
|
|
79
49
|
// 0
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
if (f.pow(f.max)(0n) !== 0n) {
|
|
84
|
-
throw '0**max';
|
|
85
|
-
}
|
|
50
|
+
assertEq(f.pow(0n)(0n), 1n);
|
|
51
|
+
assertEq(f.pow(f.max)(0n), 0n);
|
|
86
52
|
// 1
|
|
87
53
|
test(1n);
|
|
88
54
|
// 2
|
|
89
55
|
test(2n);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (f.pow(3n)(2n) !== 8n) {
|
|
94
|
-
throw '2**3';
|
|
95
|
-
}
|
|
96
|
-
if (f.pow(128n)(2n) !== 1n << 128n) {
|
|
97
|
-
throw '2**128';
|
|
98
|
-
}
|
|
56
|
+
assertEq(f.pow(2n)(2n), 4n);
|
|
57
|
+
assertEq(f.pow(3n)(2n), 8n);
|
|
58
|
+
assertEq(f.pow(128n)(2n), 1n << 128n);
|
|
99
59
|
// 3
|
|
100
60
|
test(3n);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (f.pow(100n)(3n) !== 3n ** 100n) {
|
|
108
|
-
throw '3**100';
|
|
109
|
-
}
|
|
110
|
-
if (f.pow(110n)(3n) !== 3n ** 110n) {
|
|
111
|
-
throw '3**110';
|
|
112
|
-
}
|
|
113
|
-
if (f.pow(120n)(3n) !== 3n ** 120n) {
|
|
114
|
-
throw '3**120';
|
|
115
|
-
}
|
|
116
|
-
if (f.pow(121n)(3n) !== 3n ** 121n) {
|
|
117
|
-
throw '3**121';
|
|
118
|
-
}
|
|
61
|
+
assertEq(f.pow(2n)(3n), 9n);
|
|
62
|
+
assertEq(f.pow(3n)(3n), 27n);
|
|
63
|
+
assertEq(f.pow(100n)(3n), 3n ** 100n);
|
|
64
|
+
assertEq(f.pow(110n)(3n), 3n ** 110n);
|
|
65
|
+
assertEq(f.pow(120n)(3n), 3n ** 120n);
|
|
66
|
+
assertEq(f.pow(121n)(3n), 3n ** 121n);
|
|
119
67
|
//
|
|
120
68
|
test(f.middle);
|
|
121
69
|
test(f.max - 1n);
|
|
@@ -123,18 +71,13 @@ export const proof = {
|
|
|
123
71
|
},
|
|
124
72
|
sqrtExample: () => {
|
|
125
73
|
const field = prime_field(7n);
|
|
126
|
-
|
|
127
|
-
if (root !== 2n) {
|
|
128
|
-
throw root;
|
|
129
|
-
}
|
|
74
|
+
assertEq(sqrt(field)(4n), 2n);
|
|
130
75
|
},
|
|
131
76
|
sqrt: () => {
|
|
132
77
|
const test = a => {
|
|
133
78
|
const a2 = f.mul(a)(a);
|
|
134
79
|
const s = sqrt_f(a2);
|
|
135
|
-
|
|
136
|
-
throw 'sqrt';
|
|
137
|
-
}
|
|
80
|
+
assert(s === null || f.abs(s) === f.abs(a), 'sqrt');
|
|
138
81
|
};
|
|
139
82
|
let i = 1n;
|
|
140
83
|
while (i < 1000n) {
|
|
@@ -145,42 +88,40 @@ export const proof = {
|
|
|
145
88
|
test(f.max);
|
|
146
89
|
},
|
|
147
90
|
reduce: () => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
if (f.reduce(-1n) !== p - 1n) {
|
|
152
|
-
throw [f.reduce(-1n), p - 1n];
|
|
153
|
-
}
|
|
91
|
+
assertEq(f.reduce(13n), 13n);
|
|
92
|
+
assertEq(f.reduce(-1n), p - 1n);
|
|
154
93
|
},
|
|
155
94
|
quadRes: () => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
throw 1n;
|
|
161
|
-
}
|
|
162
|
-
if (!f.quadRes(p)) {
|
|
163
|
-
throw p;
|
|
164
|
-
}
|
|
165
|
-
if (f.quadRes(3n)) {
|
|
166
|
-
throw 3n;
|
|
167
|
-
}
|
|
95
|
+
assert(f.quadRes(0n), 0n);
|
|
96
|
+
assert(f.quadRes(1n), 1n);
|
|
97
|
+
assert(f.quadRes(p), p);
|
|
98
|
+
assert(!f.quadRes(3n), 3n);
|
|
168
99
|
const f2 = prime_field(2n);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
if (!f2.quadRes(1n)) {
|
|
173
|
-
throw '1 mod 2';
|
|
174
|
-
}
|
|
100
|
+
assert(f2.quadRes(0n), '0 mod 2');
|
|
101
|
+
assert(f2.quadRes(1n), '1 mod 2');
|
|
175
102
|
},
|
|
176
103
|
modSqrt: () => {
|
|
177
104
|
const root = modSqrt(f);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
105
|
+
assertEq(root(4n), 2n);
|
|
106
|
+
assertEq(f.pow2(root(2n)), 2n);
|
|
107
|
+
},
|
|
108
|
+
div: () => {
|
|
109
|
+
assertEq(f.div(6n)(2n), 3n);
|
|
110
|
+
assertEq(f.div(0n)(5n), 0n);
|
|
111
|
+
assertEq(f.div(1n)(1n), 1n);
|
|
112
|
+
},
|
|
113
|
+
pow3: () => {
|
|
114
|
+
assertEq(f.pow3(0n), 0n);
|
|
115
|
+
assertEq(f.pow3(1n), 1n);
|
|
116
|
+
assertEq(f.pow3(2n), 8n);
|
|
117
|
+
assertEq(f.pow3(3n), 27n);
|
|
118
|
+
assertEq(f.pow3(10n), 1000n);
|
|
119
|
+
},
|
|
120
|
+
abs: () => {
|
|
121
|
+
assertEq(f.abs(0n), 0n);
|
|
122
|
+
assertEq(f.abs(1n), 1n);
|
|
123
|
+
assertEq(f.abs(f.neg(1n)), 1n);
|
|
124
|
+
assertEq(f.abs(f.middle), f.middle);
|
|
184
125
|
},
|
|
185
126
|
};
|
|
186
127
|
}
|