capdag 1.306.150 → 1.361.331
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/LICENSE +23 -0
- package/README.md +20 -4
- package/RULES.md +1 -1
- package/build-browser.js +90 -187
- package/cap-fab-renderer.js +26 -50
- package/capdag.js +117 -155
- package/formal/index.d.ts +74 -0
- package/formal/index.js +185 -0
- package/formal/program.wasm +0 -0
- package/machine-parser.js +8 -5
- package/package.json +14 -5
- package/planner.js +1 -3
- package/capdag.test.js +0 -8003
package/capdag.js
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
// Cap URN JavaScript Implementation
|
|
2
2
|
// Follows the exact same rules as Rust, Go, and Objective-C implementations
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
3
|
+
//
|
|
4
|
+
// Dispatch, acceptance, equivalence and specificity are decided by code
|
|
5
|
+
// generated from the proved model in ../formal (Lean) by lungo, in ./formal,
|
|
6
|
+
// not written here. It runs as WebAssembly, instantiated once when this module
|
|
7
|
+
// is first imported.
|
|
8
|
+
|
|
9
|
+
import { TaggedUrn } from 'tagged-urn';
|
|
10
|
+
import * as machineParser from './machine-parser.js';
|
|
11
|
+
import { load } from './formal/index.js';
|
|
12
|
+
|
|
13
|
+
const model = await load();
|
|
14
|
+
|
|
15
|
+
// Node's modules, for what works with the file system and with processes:
|
|
16
|
+
// cartridge discovery, installation records and directory hashes. They exist
|
|
17
|
+
// only under Node; elsewhere this module loads without them, and asking for
|
|
18
|
+
// them there is an error naming what needed them.
|
|
19
|
+
const node = (typeof process !== 'undefined' && process.versions && process.versions.node)
|
|
20
|
+
? {
|
|
21
|
+
fs: await import('node:fs'),
|
|
22
|
+
path: await import('node:path'),
|
|
23
|
+
crypto: await import('node:crypto'),
|
|
24
|
+
childProcess: await import('node:child_process'),
|
|
25
|
+
}
|
|
26
|
+
: null;
|
|
27
|
+
|
|
28
|
+
function nodeModules(what) {
|
|
29
|
+
if (node === null) {
|
|
30
|
+
throw new Error(`capdag: ${what} needs Node's file system and processes, which this runtime does not have`);
|
|
31
|
+
}
|
|
32
|
+
return node;
|
|
33
|
+
}
|
|
10
34
|
|
|
11
35
|
/**
|
|
12
36
|
* Error types for Cap URN operations
|
|
@@ -83,7 +107,7 @@ function processDirectionTag(taggedUrn, tagName) {
|
|
|
83
107
|
*/
|
|
84
108
|
function canonicalizeDirectionSpec(spec, tagName) {
|
|
85
109
|
if (spec === 'media:' || spec === '*') {
|
|
86
|
-
return
|
|
110
|
+
return 'media:';
|
|
87
111
|
}
|
|
88
112
|
|
|
89
113
|
try {
|
|
@@ -106,7 +130,7 @@ function canonicalizeDirectionSpec(spec, tagName) {
|
|
|
106
130
|
*/
|
|
107
131
|
function validatePreservedDirectionSpec(spec, tagName) {
|
|
108
132
|
if (spec === 'media:' || spec === '*') {
|
|
109
|
-
return
|
|
133
|
+
return 'media:';
|
|
110
134
|
}
|
|
111
135
|
|
|
112
136
|
try {
|
|
@@ -195,6 +219,27 @@ function validateNonStructuralTags(tags) {
|
|
|
195
219
|
}
|
|
196
220
|
}
|
|
197
221
|
|
|
222
|
+
/**
|
|
223
|
+
* A tagged URN as capdag's model takes it. Each program generated for
|
|
224
|
+
* JavaScript runs in a WebAssembly instance of its own, so tagged-urn's model
|
|
225
|
+
* value of a URN cannot pass here: this program makes its own, from the same
|
|
226
|
+
* tags, with the same function of the same model.
|
|
227
|
+
*/
|
|
228
|
+
function modelUrn(urn) {
|
|
229
|
+
const made = model.make(urn.prefix, urn.modelTags());
|
|
230
|
+
if (made === null) {
|
|
231
|
+
throw new Error(`capdag: the model refused ${urn.toString()}, whose keys are sorted`);
|
|
232
|
+
}
|
|
233
|
+
return made;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const MODEL_EFFECTS = Object.freeze({
|
|
237
|
+
declared: Object.freeze({ kind: 'declared' }),
|
|
238
|
+
none: Object.freeze({ kind: 'none' }),
|
|
239
|
+
patch: Object.freeze({ kind: 'patch' }),
|
|
240
|
+
'?': Object.freeze({ kind: 'unspecified' }),
|
|
241
|
+
});
|
|
242
|
+
|
|
198
243
|
class CapUrn {
|
|
199
244
|
// Per-axis weights for cap-URN specificity. Two orders of
|
|
200
245
|
// magnitude separate each axis to keep them in distinct digit
|
|
@@ -224,6 +269,20 @@ class CapUrn {
|
|
|
224
269
|
}
|
|
225
270
|
validateNonStructuralTags(this.tags);
|
|
226
271
|
this._validateAdmissible();
|
|
272
|
+
// The same cap on the proved model's side: its three URNs and its effect.
|
|
273
|
+
// Dispatch, acceptance, equivalence and specificity are asked of it. Made
|
|
274
|
+
// here, from the same fields, and the cap is frozen, so the two can never
|
|
275
|
+
// describe different caps; it is not enumerable, so it is not part of what
|
|
276
|
+
// a cap serializes or compares as.
|
|
277
|
+
const formal = {
|
|
278
|
+
input: modelUrn(MediaUrn.fromString(this.inSpec)._urn),
|
|
279
|
+
output: modelUrn(MediaUrn.fromString(this.outSpec)._urn),
|
|
280
|
+
other: modelUrn(new TaggedUrn('cap', this.tags)),
|
|
281
|
+
effect: MODEL_EFFECTS[this.effectValue],
|
|
282
|
+
};
|
|
283
|
+
Object.defineProperty(this, 'formal', { value: formal, enumerable: false });
|
|
284
|
+
Object.freeze(this.tags);
|
|
285
|
+
Object.freeze(this);
|
|
227
286
|
}
|
|
228
287
|
|
|
229
288
|
/**
|
|
@@ -604,51 +663,10 @@ class CapUrn {
|
|
|
604
663
|
if (!request) {
|
|
605
664
|
return true;
|
|
606
665
|
}
|
|
607
|
-
|
|
608
|
-
//
|
|
609
|
-
// the
|
|
610
|
-
|
|
611
|
-
const capIn = MediaUrn.fromString(this.inSpec);
|
|
612
|
-
const requestIn = MediaUrn.fromString(request.inSpec);
|
|
613
|
-
if (!capIn.accepts(requestIn)) {
|
|
614
|
-
return false;
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
// Output direction: candidate output must conform to requested output.
|
|
619
|
-
// `media:` on the pattern side is wildcard top and skips the check.
|
|
620
|
-
if (this.outSpec !== 'media:' && this.outSpec !== '*') {
|
|
621
|
-
const capOut = MediaUrn.fromString(this.outSpec);
|
|
622
|
-
const requestOut = MediaUrn.fromString(request.outSpec);
|
|
623
|
-
if (!capOut.conformsTo(requestOut)) {
|
|
624
|
-
return false;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
if (this.effectValue !== CapEffect.ANY && this.effectValue !== request.effectValue) {
|
|
629
|
-
return false;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Y-axis: every tag's per-key match runs through the six-form
|
|
633
|
-
// truth table (taggedUrnValuesMatch). Walk the union of all keys
|
|
634
|
-
// appearing on either side so missing-on-pattern and
|
|
635
|
-
// missing-on-instance cells both get evaluated.
|
|
636
|
-
const allKeys = new Set([
|
|
637
|
-
...Object.keys(this.tags),
|
|
638
|
-
...Object.keys(request.tags),
|
|
639
|
-
]);
|
|
640
|
-
for (const key of allKeys) {
|
|
641
|
-
const patt = Object.prototype.hasOwnProperty.call(this.tags, key)
|
|
642
|
-
? this.tags[key]
|
|
643
|
-
: undefined;
|
|
644
|
-
const inst = Object.prototype.hasOwnProperty.call(request.tags, key)
|
|
645
|
-
? request.tags[key]
|
|
646
|
-
: undefined;
|
|
647
|
-
if (!taggedUrnValuesMatch(inst, patt)) {
|
|
648
|
-
return false;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
return true;
|
|
666
|
+
// Decided by the proved model (CapDAG.Exec.accepts). The cap-tag axis runs
|
|
667
|
+
// opposite to isDispatchable's: this is the pattern relation, dispatch is
|
|
668
|
+
// the routing one.
|
|
669
|
+
return model.accepts(this.formal, request.formal);
|
|
652
670
|
}
|
|
653
671
|
|
|
654
672
|
/**
|
|
@@ -689,16 +707,8 @@ class CapUrn {
|
|
|
689
707
|
* @returns {number} The specificity score
|
|
690
708
|
*/
|
|
691
709
|
specificity() {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
let yScore = 0;
|
|
696
|
-
for (const value of Object.values(this.tags)) {
|
|
697
|
-
yScore += scoreTagValue(value);
|
|
698
|
-
}
|
|
699
|
-
return CapUrn.WEIGHT_OUT * outUrn.specificity()
|
|
700
|
-
+ CapUrn.WEIGHT_IN * inUrn.specificity()
|
|
701
|
-
+ yScore;
|
|
710
|
+
// Computed by the proved model (CapDAG.Exec.specificity).
|
|
711
|
+
return Number(model.specificity(this.formal));
|
|
702
712
|
}
|
|
703
713
|
|
|
704
714
|
/**
|
|
@@ -781,7 +791,7 @@ class CapUrn {
|
|
|
781
791
|
* @returns {boolean}
|
|
782
792
|
*/
|
|
783
793
|
isComparable(other) {
|
|
784
|
-
return this.
|
|
794
|
+
return model.comparable(this.formal, other.formal);
|
|
785
795
|
}
|
|
786
796
|
|
|
787
797
|
/**
|
|
@@ -792,7 +802,7 @@ class CapUrn {
|
|
|
792
802
|
* @returns {boolean}
|
|
793
803
|
*/
|
|
794
804
|
isEquivalent(other) {
|
|
795
|
-
return this.
|
|
805
|
+
return model.equivalent(this.formal, other.formal);
|
|
796
806
|
}
|
|
797
807
|
|
|
798
808
|
/**
|
|
@@ -857,45 +867,13 @@ class CapUrn {
|
|
|
857
867
|
* @returns {boolean}
|
|
858
868
|
*/
|
|
859
869
|
isDispatchable(request) {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (request.inSpec === 'media:') return true;
|
|
868
|
-
if (this.inSpec === 'media:') return true;
|
|
869
|
-
return MediaUrn.fromString(request.inSpec).conformsTo(MediaUrn.fromString(this.inSpec));
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
_outputDispatchable(request) {
|
|
873
|
-
if (request.outSpec === 'media:') return true;
|
|
874
|
-
if (this.outSpec === 'media:') return false;
|
|
875
|
-
return MediaUrn.fromString(this.outSpec).conformsTo(MediaUrn.fromString(request.outSpec));
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
_effectDispatchable(request) {
|
|
879
|
-
return request.effectValue === CapEffect.ANY || this.effectValue === request.effectValue;
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
_capTagsDispatchable(request) {
|
|
883
|
-
const allKeys = new Set([
|
|
884
|
-
...Object.keys(this.tags),
|
|
885
|
-
...Object.keys(request.tags),
|
|
886
|
-
]);
|
|
887
|
-
for (const key of allKeys) {
|
|
888
|
-
const patt = Object.prototype.hasOwnProperty.call(request.tags, key)
|
|
889
|
-
? request.tags[key]
|
|
890
|
-
: undefined;
|
|
891
|
-
const inst = Object.prototype.hasOwnProperty.call(this.tags, key)
|
|
892
|
-
? this.tags[key]
|
|
893
|
-
: undefined;
|
|
894
|
-
if (!taggedUrnValuesMatch(inst, patt)) {
|
|
895
|
-
return false;
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
return true;
|
|
870
|
+
// Decided by the proved model (CapDAG.Exec.dispatch): every axis is a type.
|
|
871
|
+
// The request's input refines the candidate's, the candidate's output
|
|
872
|
+
// refines the request's, the effect matches unless the request says
|
|
873
|
+
// ?effect, and the candidate's cap-tags refine the request's. `media:` on
|
|
874
|
+
// a request's input is a type — "may send anything" — so only a candidate
|
|
875
|
+
// that accepts anything serves it, which is what makes dispatch compose.
|
|
876
|
+
return model.dispatch(this.formal, request.formal);
|
|
899
877
|
}
|
|
900
878
|
|
|
901
879
|
/**
|
|
@@ -6172,8 +6150,7 @@ class CartridgeJson {
|
|
|
6172
6150
|
* @throws {CartridgeJsonError}
|
|
6173
6151
|
*/
|
|
6174
6152
|
static readFromDir(versionDir, expectedSlug) {
|
|
6175
|
-
const fs =
|
|
6176
|
-
const path = require('path');
|
|
6153
|
+
const { fs, path } = nodeModules('reading cartridge.json');
|
|
6177
6154
|
const jsonPath = path.join(versionDir, 'cartridge.json');
|
|
6178
6155
|
|
|
6179
6156
|
if (!fs.existsSync(jsonPath)) {
|
|
@@ -6255,7 +6232,7 @@ class CartridgeJson {
|
|
|
6255
6232
|
* @returns {string}
|
|
6256
6233
|
*/
|
|
6257
6234
|
resolveEntryPoint(versionDir) {
|
|
6258
|
-
const path =
|
|
6235
|
+
const { path } = nodeModules('resolving an entry point');
|
|
6259
6236
|
return path.join(versionDir, this.entry);
|
|
6260
6237
|
}
|
|
6261
6238
|
}
|
|
@@ -6272,9 +6249,7 @@ class CartridgeJson {
|
|
|
6272
6249
|
* @returns {string} Lowercase hex SHA256.
|
|
6273
6250
|
*/
|
|
6274
6251
|
function hashCartridgeDirectory(dir) {
|
|
6275
|
-
const fs =
|
|
6276
|
-
const path = require('path');
|
|
6277
|
-
const crypto = require('crypto');
|
|
6252
|
+
const { fs, path, crypto } = nodeModules('hashing a cartridge directory');
|
|
6278
6253
|
|
|
6279
6254
|
const files = [];
|
|
6280
6255
|
const collect = (current) => {
|
|
@@ -6577,7 +6552,7 @@ function encodeHelloFrame() {
|
|
|
6577
6552
|
* @throws {Error} when the handshake/probe fails.
|
|
6578
6553
|
*/
|
|
6579
6554
|
function probeCartridgeCapGroups(entryPath) {
|
|
6580
|
-
const { spawn } =
|
|
6555
|
+
const { spawn } = nodeModules('probing a cartridge').childProcess;
|
|
6581
6556
|
return new Promise((resolve, reject) => {
|
|
6582
6557
|
let child;
|
|
6583
6558
|
try {
|
|
@@ -6714,8 +6689,7 @@ function probeCartridgeCapGroups(entryPath) {
|
|
|
6714
6689
|
* @returns {Promise<Array<DiscoveredCartridge>>}
|
|
6715
6690
|
*/
|
|
6716
6691
|
async function discoverCartridges(cartridgesRoot, identity) {
|
|
6717
|
-
const fs =
|
|
6718
|
-
const path = require('path');
|
|
6692
|
+
const { fs, path } = nodeModules('discovering cartridges');
|
|
6719
6693
|
const discovered = [];
|
|
6720
6694
|
|
|
6721
6695
|
let rootStat;
|
|
@@ -6755,8 +6729,7 @@ async function discoverCartridges(cartridgesRoot, identity) {
|
|
|
6755
6729
|
* Mirrors capdag::cartridge_discovery::scan_channel_root.
|
|
6756
6730
|
*/
|
|
6757
6731
|
async function scanChannelRoot(scanRoot, expectedSlug, identity, discovered) {
|
|
6758
|
-
const fs =
|
|
6759
|
-
const path = require('path');
|
|
6732
|
+
const { fs, path } = nodeModules('discovering cartridges');
|
|
6760
6733
|
|
|
6761
6734
|
let nameEntries;
|
|
6762
6735
|
try {
|
|
@@ -7645,7 +7618,6 @@ class Machine {
|
|
|
7645
7618
|
// ============================================================================
|
|
7646
7619
|
|
|
7647
7620
|
// Load the Peggy-generated parser
|
|
7648
|
-
const machineParser = require('./machine-parser.js');
|
|
7649
7621
|
|
|
7650
7622
|
/**
|
|
7651
7623
|
* Assign a media URN to a node, or check consistency if already assigned.
|
|
@@ -8026,22 +7998,13 @@ class MediaRegistryEntry {
|
|
|
8026
7998
|
* implementations (capdag, capdag-js, capdag-py, capdag-go, capdag-objc)
|
|
8027
7999
|
* use this same algorithm so a URN's key is identical across languages.
|
|
8028
8000
|
*
|
|
8029
|
-
*
|
|
8030
|
-
*
|
|
8031
|
-
* also has the synchronous `crypto` module. We prefer subtle for
|
|
8032
|
-
* portability and fall back to the Node module when subtle is absent.
|
|
8001
|
+
* `crypto.subtle` is on `globalThis` in browsers and in every Node this
|
|
8002
|
+
* package supports.
|
|
8033
8003
|
*/
|
|
8034
8004
|
async function sha256Hex(s) {
|
|
8035
8005
|
const utf8 = new TextEncoder().encode(s);
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
8039
|
-
}
|
|
8040
|
-
// Node CommonJS fallback. require() may throw in strict ESM contexts;
|
|
8041
|
-
// we let it propagate because every supported runtime has a crypto API.
|
|
8042
|
-
// eslint-disable-next-line global-require
|
|
8043
|
-
const nodeCrypto = require('crypto');
|
|
8044
|
-
return nodeCrypto.createHash('sha256').update(utf8).digest('hex');
|
|
8006
|
+
const buf = await globalThis.crypto.subtle.digest('SHA-256', utf8);
|
|
8007
|
+
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
8045
8008
|
}
|
|
8046
8009
|
|
|
8047
8010
|
/**
|
|
@@ -8445,12 +8408,7 @@ class Manifest {
|
|
|
8445
8408
|
}
|
|
8446
8409
|
}
|
|
8447
8410
|
|
|
8448
|
-
|
|
8449
|
-
// PlanMachines/DiscoverConvergentTargets proto surface).
|
|
8450
|
-
const planner = require('./planner.js');
|
|
8451
|
-
|
|
8452
|
-
// Export for CommonJS
|
|
8453
|
-
module.exports = {
|
|
8411
|
+
export {
|
|
8454
8412
|
// Registry trust vocabulary — one verdict per registry, shared by every
|
|
8455
8413
|
// cartridge that claims provenance from it.
|
|
8456
8414
|
RegistryVerdict,
|
|
@@ -8466,24 +8424,6 @@ module.exports = {
|
|
|
8466
8424
|
registryVerdictRemedy,
|
|
8467
8425
|
MANIFEST_SIG_FORMAT,
|
|
8468
8426
|
RELEASE_KEY_CERT_FORMAT,
|
|
8469
|
-
// Planner plan-space vocabulary
|
|
8470
|
-
PlanStateError: planner.PlanStateError,
|
|
8471
|
-
ConvergencePresence: planner.ConvergencePresence,
|
|
8472
|
-
ConvergenceLocation: planner.ConvergenceLocation,
|
|
8473
|
-
ConvergenceMechanism: planner.ConvergenceMechanism,
|
|
8474
|
-
ConvergenceArity: planner.ConvergenceArity,
|
|
8475
|
-
DivergencePresence: planner.DivergencePresence,
|
|
8476
|
-
DivergenceLocation: planner.DivergenceLocation,
|
|
8477
|
-
RankPolicy: planner.RankPolicy,
|
|
8478
|
-
PlanMode: planner.PlanMode,
|
|
8479
|
-
PlanRequest: planner.PlanRequest,
|
|
8480
|
-
parsePlanApex: planner.parsePlanApex,
|
|
8481
|
-
parsePlanProfile: planner.parsePlanProfile,
|
|
8482
|
-
parsePlanCost: planner.parsePlanCost,
|
|
8483
|
-
parsePlanCandidate: planner.parsePlanCandidate,
|
|
8484
|
-
parsePlanCandidates: planner.parsePlanCandidates,
|
|
8485
|
-
parseConvergentTarget: planner.parseConvergentTarget,
|
|
8486
|
-
parseConvergentTargets: planner.parseConvergentTargets,
|
|
8487
8427
|
ALIAS_TARGET_CAP,
|
|
8488
8428
|
ALIAS_TARGET_MEDIA,
|
|
8489
8429
|
tokenIsUrn,
|
|
@@ -8541,7 +8481,7 @@ module.exports = {
|
|
|
8541
8481
|
MEDIA_OBJECT,
|
|
8542
8482
|
// List types
|
|
8543
8483
|
MEDIA_LIST,
|
|
8544
|
-
MEDIA_TEXTABLE_LIST
|
|
8484
|
+
MEDIA_STRING_LIST as MEDIA_TEXTABLE_LIST,
|
|
8545
8485
|
MEDIA_STRING_LIST,
|
|
8546
8486
|
MEDIA_INTEGER_LIST,
|
|
8547
8487
|
MEDIA_NUMBER_LIST,
|
|
@@ -8705,3 +8645,25 @@ module.exports = {
|
|
|
8705
8645
|
MediaRegistryEntry,
|
|
8706
8646
|
FabricRegistryClient,
|
|
8707
8647
|
};
|
|
8648
|
+
|
|
8649
|
+
// Unified configurable planner vocabulary (mirrors Rust plan_space.rs and the
|
|
8650
|
+
// PlanMachines/DiscoverConvergentTargets proto surface).
|
|
8651
|
+
export {
|
|
8652
|
+
PlanStateError,
|
|
8653
|
+
ConvergencePresence,
|
|
8654
|
+
ConvergenceLocation,
|
|
8655
|
+
ConvergenceMechanism,
|
|
8656
|
+
ConvergenceArity,
|
|
8657
|
+
DivergencePresence,
|
|
8658
|
+
DivergenceLocation,
|
|
8659
|
+
RankPolicy,
|
|
8660
|
+
PlanMode,
|
|
8661
|
+
PlanRequest,
|
|
8662
|
+
parsePlanApex,
|
|
8663
|
+
parsePlanProfile,
|
|
8664
|
+
parsePlanCost,
|
|
8665
|
+
parsePlanCandidate,
|
|
8666
|
+
parsePlanCandidates,
|
|
8667
|
+
parseConvergentTarget,
|
|
8668
|
+
parseConvergentTargets,
|
|
8669
|
+
} from './planner.js';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Generated by lungo 1.78.3254 from Lean 4.34.1 for program capdagFormal. Do not edit.
|
|
2
|
+
import * as L from "lungo-ts";
|
|
3
|
+
|
|
4
|
+
/** Lean's CapDAG.Exec.WfCap. */
|
|
5
|
+
export interface WfCap {
|
|
6
|
+
readonly input: Wf;
|
|
7
|
+
readonly output: Wf;
|
|
8
|
+
readonly other: Wf;
|
|
9
|
+
readonly effect: Effect;
|
|
10
|
+
}
|
|
11
|
+
export function wfCapType(): L.Type<WfCap>;
|
|
12
|
+
|
|
13
|
+
/** Lean's CapDAG.Effect. */
|
|
14
|
+
export type Effect =
|
|
15
|
+
| { readonly kind: "unspecified" }
|
|
16
|
+
| { readonly kind: "declared" }
|
|
17
|
+
| { readonly kind: "none" }
|
|
18
|
+
| { readonly kind: "patch" }
|
|
19
|
+
;
|
|
20
|
+
export function effectType(): L.Type<Effect>;
|
|
21
|
+
|
|
22
|
+
/** Lean's TaggedUrn.Constraint. */
|
|
23
|
+
export type Constraint =
|
|
24
|
+
| { readonly kind: "missing" }
|
|
25
|
+
| { readonly kind: "unconstrained" }
|
|
26
|
+
| { readonly kind: "optionalNot"; readonly value: string }
|
|
27
|
+
| { readonly kind: "present" }
|
|
28
|
+
| { readonly kind: "presentNot"; readonly value: string }
|
|
29
|
+
| { readonly kind: "exact"; readonly value: string }
|
|
30
|
+
| { readonly kind: "absent" }
|
|
31
|
+
;
|
|
32
|
+
export function constraintType(): L.Type<Constraint>;
|
|
33
|
+
|
|
34
|
+
/** Lean's TaggedUrn.Exec.Wf, held by handle: only the program's functions make and read its values. */
|
|
35
|
+
export class Wf extends L.Opaque {
|
|
36
|
+
private constructor();
|
|
37
|
+
}
|
|
38
|
+
export function wfType(): L.Type<Wf>;
|
|
39
|
+
|
|
40
|
+
/** The layout fingerprint and descriptor of each type, by Lean name, for modules using them. */
|
|
41
|
+
export const leanTypes: {
|
|
42
|
+
readonly [lean: string]: { readonly fingerprint: string; readonly type: (...args: L.Type<any>[]) => L.Type<any> };
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** The Lean program capdagFormal. */
|
|
46
|
+
export class CapdagFormal {
|
|
47
|
+
private constructor();
|
|
48
|
+
/** Lean's CapDAG.Exec.accepts : CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Bool */
|
|
49
|
+
accepts(pattern: WfCap, request: WfCap): boolean;
|
|
50
|
+
/** Lean's CapDAG.Exec.comparable : CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Bool */
|
|
51
|
+
comparable(a: WfCap, b: WfCap): boolean;
|
|
52
|
+
/** Lean's CapDAG.Exec.dispatch : CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Bool */
|
|
53
|
+
dispatch(candidate: WfCap, request: WfCap): boolean;
|
|
54
|
+
/** Lean's CapDAG.Exec.effectOk : CapDAG.Effect → CapDAG.Effect → Bool */
|
|
55
|
+
effectOk(candidate: Effect, request: Effect): boolean;
|
|
56
|
+
/** Lean's CapDAG.Exec.equivalent : CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Bool */
|
|
57
|
+
equivalent(a: WfCap, b: WfCap): boolean;
|
|
58
|
+
/** Lean's CapDAG.Exec.rankingKey : CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Nat × Nat */
|
|
59
|
+
rankingKey(candidate: WfCap, request: WfCap): [bigint, bigint];
|
|
60
|
+
/** Lean's CapDAG.Exec.select : List CapDAG.Exec.WfCap → CapDAG.Exec.WfCap → Option CapDAG.Exec.WfCap */
|
|
61
|
+
select(candidates: Array<WfCap>, request: WfCap): L.Option<WfCap>;
|
|
62
|
+
/** Lean's CapDAG.Exec.specificity : CapDAG.Exec.WfCap → Nat */
|
|
63
|
+
specificity(c: WfCap): bigint;
|
|
64
|
+
/** Lean's TaggedUrn.Exec.make : String → List (String × TaggedUrn.Constraint) → Option TaggedUrn.Exec.Wf */
|
|
65
|
+
make(scheme: string, tags: Array<[string, Constraint]>): L.Option<Wf>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface LoadOptions {
|
|
69
|
+
/** The program module (default: `program.wasm` next to this file). */
|
|
70
|
+
module?: WebAssembly.Module | BufferSource;
|
|
71
|
+
wasi?: L.Wasi;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function load(options?: LoadOptions): Promise<CapdagFormal>;
|
package/formal/index.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// Generated by lungo 1.78.3254 from Lean 4.34.1 for program capdagFormal. Do not edit.
|
|
2
|
+
import * as L from "lungo-ts";
|
|
3
|
+
|
|
4
|
+
async function programModule() {
|
|
5
|
+
const url = new URL("./program.wasm", import.meta.url);
|
|
6
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
7
|
+
const { readFile } = await import("node:fs/promises");
|
|
8
|
+
return readFile(url);
|
|
9
|
+
}
|
|
10
|
+
const response = await fetch(url);
|
|
11
|
+
if (!response.ok) throw new Error(`cannot load ${url}: ${response.status}`);
|
|
12
|
+
return response.arrayBuffer();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Describes CapDAG.Exec.WfCap for polymorphic functions. */
|
|
16
|
+
export function wfCapType() {
|
|
17
|
+
return new L.Type(
|
|
18
|
+
L.inductiveExpr(0),
|
|
19
|
+
(w, v) => {
|
|
20
|
+
if (typeof v !== "object" || v === null) throw new L.MalformedError("not a CapDAG.Exec.WfCap");
|
|
21
|
+
w.u32(0);
|
|
22
|
+
wfType().encode(w, v.input);
|
|
23
|
+
wfType().encode(w, v.output);
|
|
24
|
+
wfType().encode(w, v.other);
|
|
25
|
+
effectType().encode(w, v.effect);
|
|
26
|
+
},
|
|
27
|
+
(r) => {
|
|
28
|
+
const c = r.u32();
|
|
29
|
+
if (c !== 0) throw new L.MalformedError(`constructor index ${c} of CapDAG.Exec.WfCap`);
|
|
30
|
+
return ({ input: wfType().decode(r), output: wfType().decode(r), other: wfType().decode(r), effect: effectType().decode(r) });
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Describes CapDAG.Effect for polymorphic functions. */
|
|
36
|
+
export function effectType() {
|
|
37
|
+
return new L.Type(
|
|
38
|
+
L.inductiveExpr(1),
|
|
39
|
+
(w, v) => {
|
|
40
|
+
if (typeof v !== "object" || v === null) throw new L.MalformedError("not a CapDAG.Effect");
|
|
41
|
+
switch (v.kind) {
|
|
42
|
+
case "unspecified":
|
|
43
|
+
w.u32(0);
|
|
44
|
+
return;
|
|
45
|
+
case "declared":
|
|
46
|
+
w.u32(1);
|
|
47
|
+
return;
|
|
48
|
+
case "none":
|
|
49
|
+
w.u32(2);
|
|
50
|
+
return;
|
|
51
|
+
case "patch":
|
|
52
|
+
w.u32(3);
|
|
53
|
+
return;
|
|
54
|
+
default:
|
|
55
|
+
throw new L.MalformedError(`${String(v.kind)} is not a constructor of CapDAG.Effect`);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
(r) => {
|
|
59
|
+
const c = r.u32();
|
|
60
|
+
switch (c) {
|
|
61
|
+
case 0: return ({ kind: "unspecified" });
|
|
62
|
+
case 1: return ({ kind: "declared" });
|
|
63
|
+
case 2: return ({ kind: "none" });
|
|
64
|
+
case 3: return ({ kind: "patch" });
|
|
65
|
+
default: throw new L.MalformedError(`constructor index ${c} of CapDAG.Effect`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Describes TaggedUrn.Constraint for polymorphic functions. */
|
|
72
|
+
export function constraintType() {
|
|
73
|
+
return new L.Type(
|
|
74
|
+
L.inductiveExpr(2),
|
|
75
|
+
(w, v) => {
|
|
76
|
+
if (typeof v !== "object" || v === null) throw new L.MalformedError("not a TaggedUrn.Constraint");
|
|
77
|
+
switch (v.kind) {
|
|
78
|
+
case "missing":
|
|
79
|
+
w.u32(0);
|
|
80
|
+
return;
|
|
81
|
+
case "unconstrained":
|
|
82
|
+
w.u32(1);
|
|
83
|
+
return;
|
|
84
|
+
case "optionalNot":
|
|
85
|
+
w.u32(2);
|
|
86
|
+
L.STRING.encode(w, v.value);
|
|
87
|
+
return;
|
|
88
|
+
case "present":
|
|
89
|
+
w.u32(3);
|
|
90
|
+
return;
|
|
91
|
+
case "presentNot":
|
|
92
|
+
w.u32(4);
|
|
93
|
+
L.STRING.encode(w, v.value);
|
|
94
|
+
return;
|
|
95
|
+
case "exact":
|
|
96
|
+
w.u32(5);
|
|
97
|
+
L.STRING.encode(w, v.value);
|
|
98
|
+
return;
|
|
99
|
+
case "absent":
|
|
100
|
+
w.u32(6);
|
|
101
|
+
return;
|
|
102
|
+
default:
|
|
103
|
+
throw new L.MalformedError(`${String(v.kind)} is not a constructor of TaggedUrn.Constraint`);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
(r) => {
|
|
107
|
+
const c = r.u32();
|
|
108
|
+
switch (c) {
|
|
109
|
+
case 0: return ({ kind: "missing" });
|
|
110
|
+
case 1: return ({ kind: "unconstrained" });
|
|
111
|
+
case 2: return ({ kind: "optionalNot", value: L.STRING.decode(r) });
|
|
112
|
+
case 3: return ({ kind: "present" });
|
|
113
|
+
case 4: return ({ kind: "presentNot", value: L.STRING.decode(r) });
|
|
114
|
+
case 5: return ({ kind: "exact", value: L.STRING.decode(r) });
|
|
115
|
+
case 6: return ({ kind: "absent" });
|
|
116
|
+
default: throw new L.MalformedError(`constructor index ${c} of TaggedUrn.Constraint`);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Lean's TaggedUrn.Exec.Wf, held by handle: only the program's functions make and read its values. */
|
|
123
|
+
export class Wf extends L.Opaque {}
|
|
124
|
+
|
|
125
|
+
/** Describes TaggedUrn.Exec.Wf for polymorphic functions. */
|
|
126
|
+
export function wfType() {
|
|
127
|
+
return new L.Type(
|
|
128
|
+
L.inductiveExpr(3),
|
|
129
|
+
(w, v) => {
|
|
130
|
+
if (!(v instanceof Wf)) throw new L.MalformedError("not a TaggedUrn.Exec.Wf");
|
|
131
|
+
L.OPAQUE.encode(w, v);
|
|
132
|
+
},
|
|
133
|
+
(r) => new Wf(r.program, r.u64()),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The layout fingerprint and descriptor of each type, by Lean name, for modules using them. */
|
|
138
|
+
export const leanTypes = Object.freeze({
|
|
139
|
+
"CapDAG.Exec.WfCap": Object.freeze({ fingerprint: "2b8d6466d218f4ae6bc98d95bba55d98f21cac4a49446ae170993773cefdb830", type: wfCapType }),
|
|
140
|
+
"CapDAG.Effect": Object.freeze({ fingerprint: "38c7bd3c0527cda156713cd441c9b6b92bd5df8a39108fa101449a789abcb477", type: effectType }),
|
|
141
|
+
"TaggedUrn.Constraint": Object.freeze({ fingerprint: "481fc09e23c6415a7c3f05887577ec940a6ecc84b005e63476c1060b59edcac7", type: constraintType }),
|
|
142
|
+
"TaggedUrn.Exec.Wf": Object.freeze({ fingerprint: "20e9f81ad195b2f4a481e7a5dcae2b3d0de6efe7b3dc720db0e2aa3b52527785", type: wfType }),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
/** The Lean program capdagFormal. */
|
|
146
|
+
export class CapdagFormal {
|
|
147
|
+
#program;
|
|
148
|
+
constructor(program) {
|
|
149
|
+
this.#program = program;
|
|
150
|
+
}
|
|
151
|
+
accepts(pattern, request) {
|
|
152
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_daccepts", [], [[wfCapType(), pattern], [wfCapType(), request]], L.value(L.BOOL));
|
|
153
|
+
}
|
|
154
|
+
comparable(a, b) {
|
|
155
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_dcomparable", [], [[wfCapType(), a], [wfCapType(), b]], L.value(L.BOOL));
|
|
156
|
+
}
|
|
157
|
+
dispatch(candidate, request) {
|
|
158
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_ddispatch", [], [[wfCapType(), candidate], [wfCapType(), request]], L.value(L.BOOL));
|
|
159
|
+
}
|
|
160
|
+
effectOk(candidate, request) {
|
|
161
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_deffectOk", [], [[effectType(), candidate], [effectType(), request]], L.value(L.BOOL));
|
|
162
|
+
}
|
|
163
|
+
equivalent(a, b) {
|
|
164
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_dequivalent", [], [[wfCapType(), a], [wfCapType(), b]], L.value(L.BOOL));
|
|
165
|
+
}
|
|
166
|
+
rankingKey(candidate, request) {
|
|
167
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_drankingKey", [], [[wfCapType(), candidate], [wfCapType(), request]], L.value(L.pair(L.NAT, L.NAT)));
|
|
168
|
+
}
|
|
169
|
+
select(candidates, request) {
|
|
170
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_dselect", [], [[L.list(wfCapType()), candidates], [wfCapType(), request]], L.value(L.option(wfCapType())));
|
|
171
|
+
}
|
|
172
|
+
specificity(c) {
|
|
173
|
+
return this.#program.invoke("capdagFormal__call_l_CapDAG_dExec_dspecificity", [], [[wfCapType(), c]], L.value(L.NAT));
|
|
174
|
+
}
|
|
175
|
+
make(scheme, tags) {
|
|
176
|
+
return this.#program.invoke("capdagFormal__call_l_TaggedUrn_dExec_dmake", [], [[L.STRING, scheme], [L.list(L.pair(L.STRING, constraintType())), tags]], L.value(L.option(wfType())));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Instantiates the program; `options.host` implements its externs. */
|
|
181
|
+
export async function load(options = {}) {
|
|
182
|
+
const program = await L.Program.load(options.module ?? (await programModule()), { wasi: options.wasi });
|
|
183
|
+
program.types("capdagFormal__types");
|
|
184
|
+
return new CapdagFormal(program);
|
|
185
|
+
}
|
|
Binary file
|