aisp-validator 0.1.0 → 0.2.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/bin/cli.js +49 -10
- package/package.json +1 -1
- package/src/index.js +98 -7
package/bin/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { readFile } from 'fs/promises';
|
|
|
9
9
|
import { existsSync } from 'fs';
|
|
10
10
|
|
|
11
11
|
const HELP = `
|
|
12
|
-
AISP Validator - Validate AISP 5.1 documents
|
|
12
|
+
AISP Validator v0.2.0 - Validate AISP 5.1 documents
|
|
13
13
|
|
|
14
14
|
Usage:
|
|
15
15
|
aisp-validator <command> [file]
|
|
@@ -19,6 +19,7 @@ Commands:
|
|
|
19
19
|
validate <file> Validate an AISP document
|
|
20
20
|
tier <file> Get quality tier (⊘ to ◊⁺⁺)
|
|
21
21
|
density <file> Get density score (δ)
|
|
22
|
+
debug <file> Show detailed density breakdown
|
|
22
23
|
help Show this help message
|
|
23
24
|
|
|
24
25
|
Quality Tiers:
|
|
@@ -28,10 +29,16 @@ Quality Tiers:
|
|
|
28
29
|
◊⁻ Bronze δ ≥ 0.20
|
|
29
30
|
⊘ Reject δ < 0.20
|
|
30
31
|
|
|
32
|
+
Density Formula:
|
|
33
|
+
δ = (blockScore × 0.4) + (bindingScore × 0.6)
|
|
34
|
+
|
|
35
|
+
blockScore: Required blocks present (⟦Ω⟧, ⟦Σ⟧, ⟦Γ⟧, ⟦Λ⟧, ⟦Ε⟧)
|
|
36
|
+
bindingScore: Semantic operators (≜, ≔, ∀, ∃, λ, ⇒, ∈, etc.)
|
|
37
|
+
|
|
31
38
|
Examples:
|
|
32
39
|
npx aisp-validator validate spec.aisp
|
|
33
40
|
npx aisp-validator tier spec.aisp
|
|
34
|
-
npx aisp-validator spec.aisp
|
|
41
|
+
npx aisp-validator debug spec.aisp
|
|
35
42
|
`;
|
|
36
43
|
|
|
37
44
|
async function main() {
|
|
@@ -42,11 +49,16 @@ async function main() {
|
|
|
42
49
|
process.exit(0);
|
|
43
50
|
}
|
|
44
51
|
|
|
52
|
+
if (args[0] === '--version' || args[0] === '-v') {
|
|
53
|
+
console.log('aisp-validator v0.2.0');
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
let command = args[0];
|
|
46
58
|
let file = args[1];
|
|
47
59
|
|
|
48
60
|
// If first arg is a file (no command), default to validate
|
|
49
|
-
if (command && !['validate', 'tier', 'density'].includes(command)) {
|
|
61
|
+
if (command && !['validate', 'tier', 'density', 'debug'].includes(command)) {
|
|
50
62
|
file = command;
|
|
51
63
|
command = 'validate';
|
|
52
64
|
}
|
|
@@ -65,13 +77,13 @@ async function main() {
|
|
|
65
77
|
try {
|
|
66
78
|
await AISP.init();
|
|
67
79
|
const content = await readFile(file, 'utf-8');
|
|
68
|
-
const result = AISP.validate(content);
|
|
69
80
|
|
|
70
81
|
switch (command) {
|
|
71
|
-
case 'validate':
|
|
82
|
+
case 'validate': {
|
|
83
|
+
const result = AISP.validate(content);
|
|
72
84
|
if (result.valid) {
|
|
73
85
|
console.log(`✓ VALID`);
|
|
74
|
-
console.log(` Tier: ${result.tier}`);
|
|
86
|
+
console.log(` Tier: ${result.tier} ${result.tierName}`);
|
|
75
87
|
console.log(` Density (δ): ${result.delta.toFixed(3)}`);
|
|
76
88
|
console.log(` Ambiguity: ${result.ambiguity.toFixed(3)}`);
|
|
77
89
|
process.exit(0);
|
|
@@ -79,20 +91,47 @@ async function main() {
|
|
|
79
91
|
console.log(`✗ INVALID`);
|
|
80
92
|
console.log(` Error: ${result.error || `Error code ${result.errorCode}`}`);
|
|
81
93
|
if (result.tier) {
|
|
82
|
-
console.log(` Tier: ${result.tier}`);
|
|
94
|
+
console.log(` Tier: ${result.tier} ${result.tierName}`);
|
|
83
95
|
console.log(` Density (δ): ${result.delta.toFixed(3)}`);
|
|
84
96
|
}
|
|
85
97
|
process.exit(1);
|
|
86
98
|
}
|
|
87
99
|
break;
|
|
100
|
+
}
|
|
88
101
|
|
|
89
|
-
case 'tier':
|
|
90
|
-
|
|
102
|
+
case 'tier': {
|
|
103
|
+
const result = AISP.validate(content);
|
|
104
|
+
console.log(`${result.tier} ${result.tierName}`);
|
|
91
105
|
break;
|
|
106
|
+
}
|
|
92
107
|
|
|
93
|
-
case 'density':
|
|
108
|
+
case 'density': {
|
|
109
|
+
const result = AISP.validate(content);
|
|
94
110
|
console.log(result.delta.toFixed(4));
|
|
95
111
|
break;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
case 'debug': {
|
|
115
|
+
const debug = AISP.debug(content);
|
|
116
|
+
console.log(`\nAISP Density Debug`);
|
|
117
|
+
console.log(`==================`);
|
|
118
|
+
console.log(`\nTier: ${debug.tier} ${debug.tierName}`);
|
|
119
|
+
console.log(`Density (δ): ${debug.delta.toFixed(3)}`);
|
|
120
|
+
console.log(`\nScore Breakdown:`);
|
|
121
|
+
console.log(` Block Score: ${(debug.blockScore * 100).toFixed(1)}% (weight: 40%)`);
|
|
122
|
+
console.log(` Binding Score: ${(debug.bindingScore * 100).toFixed(1)}% (weight: 60%)`);
|
|
123
|
+
console.log(`\nBlocks Found: ${debug.breakdown.blocksFound}/${debug.breakdown.blocksRequired}`);
|
|
124
|
+
console.log(` Required: ⟦Ω⟧, ⟦Σ⟧, ⟦Γ⟧, ⟦Λ⟧, ⟦Ε⟧`);
|
|
125
|
+
console.log(`\nSemantic Operators: ${debug.breakdown.totalBindings}`);
|
|
126
|
+
console.log(` ≜ definitions: ${debug.breakdown.definitions}`);
|
|
127
|
+
console.log(` ≔ assignments: ${debug.breakdown.assignments}`);
|
|
128
|
+
console.log(` ∀∃ quantifiers: ${debug.breakdown.quantifiers}`);
|
|
129
|
+
console.log(` λ lambdas: ${debug.breakdown.lambdas}`);
|
|
130
|
+
console.log(` ⇒⇔ implications: ${debug.breakdown.implications}`);
|
|
131
|
+
console.log(` ∈⊆∩∪ set ops: ${debug.breakdown.setOps}`);
|
|
132
|
+
console.log(`\nFormula: δ = (${debug.blockScore.toFixed(2)} × 0.4) + (${debug.bindingScore.toFixed(2)} × 0.6) = ${debug.delta.toFixed(3)}`);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
96
135
|
}
|
|
97
136
|
} catch (err) {
|
|
98
137
|
console.error(`Error: ${err.message}`);
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -10,6 +10,63 @@ import { dirname, join } from 'path';
|
|
|
10
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
11
|
const __dirname = dirname(__filename);
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Calculate semantic density using Block Coverage + Binding Density
|
|
15
|
+
* δ = (blockScore × 0.4) + (bindingScore × 0.6)
|
|
16
|
+
* @param {string} text - AISP source
|
|
17
|
+
* @returns {object} { delta, blockScore, bindingScore, breakdown }
|
|
18
|
+
*/
|
|
19
|
+
function calculateSemanticDensity(text) {
|
|
20
|
+
// Required blocks present?
|
|
21
|
+
const blocks = ['⟦Ω', '⟦Σ', '⟦Γ', '⟦Λ', '⟦Ε'];
|
|
22
|
+
const blocksFound = blocks.filter(b => text.includes(b));
|
|
23
|
+
const blockScore = blocksFound.length / blocks.length;
|
|
24
|
+
|
|
25
|
+
// Binding density (semantic operators)
|
|
26
|
+
const definitions = (text.match(/≜/g) || []).length;
|
|
27
|
+
const assignments = (text.match(/≔/g) || []).length;
|
|
28
|
+
const quantifiers = (text.match(/[∀∃]/g) || []).length;
|
|
29
|
+
const lambdas = (text.match(/λ/g) || []).length;
|
|
30
|
+
const implications = (text.match(/[⇒⇔→↔]/g) || []).length;
|
|
31
|
+
const setOps = (text.match(/[∈⊆∩∪∅]/g) || []).length;
|
|
32
|
+
|
|
33
|
+
const totalBindings = definitions + assignments + quantifiers + lambdas + implications + setOps;
|
|
34
|
+
const bindingScore = Math.min(1, totalBindings / 20);
|
|
35
|
+
|
|
36
|
+
// Combined score
|
|
37
|
+
const delta = (blockScore * 0.4) + (bindingScore * 0.6);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
delta,
|
|
41
|
+
blockScore,
|
|
42
|
+
bindingScore,
|
|
43
|
+
breakdown: {
|
|
44
|
+
blocksFound: blocksFound.length,
|
|
45
|
+
blocksRequired: blocks.length,
|
|
46
|
+
definitions,
|
|
47
|
+
assignments,
|
|
48
|
+
quantifiers,
|
|
49
|
+
lambdas,
|
|
50
|
+
implications,
|
|
51
|
+
setOps,
|
|
52
|
+
totalBindings
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get tier from delta value
|
|
59
|
+
* @param {number} delta
|
|
60
|
+
* @returns {object} { tier, tierValue, tierName }
|
|
61
|
+
*/
|
|
62
|
+
function getTierFromDelta(delta) {
|
|
63
|
+
if (delta >= 0.75) return { tier: '◊⁺⁺', tierValue: 4, tierName: 'Platinum' };
|
|
64
|
+
if (delta >= 0.60) return { tier: '◊⁺', tierValue: 3, tierName: 'Gold' };
|
|
65
|
+
if (delta >= 0.40) return { tier: '◊', tierValue: 2, tierName: 'Silver' };
|
|
66
|
+
if (delta >= 0.20) return { tier: '◊⁻', tierValue: 1, tierName: 'Bronze' };
|
|
67
|
+
return { tier: '⊘', tierValue: 0, tierName: 'Reject' };
|
|
68
|
+
}
|
|
69
|
+
|
|
13
70
|
const AISP = {
|
|
14
71
|
_instance: null,
|
|
15
72
|
_memory: null,
|
|
@@ -74,15 +131,38 @@ const AISP = {
|
|
|
74
131
|
};
|
|
75
132
|
}
|
|
76
133
|
|
|
77
|
-
const
|
|
134
|
+
const parseResult = this._instance.aisp_validate(docId);
|
|
135
|
+
|
|
136
|
+
// Use semantic density calculation instead of WASM density
|
|
137
|
+
const densityResult = calculateSemanticDensity(source);
|
|
138
|
+
const tierResult = getTierFromDelta(densityResult.delta);
|
|
78
139
|
|
|
79
140
|
return {
|
|
80
|
-
valid:
|
|
81
|
-
tier:
|
|
82
|
-
tierValue:
|
|
83
|
-
|
|
141
|
+
valid: parseResult === 0,
|
|
142
|
+
tier: tierResult.tier,
|
|
143
|
+
tierValue: tierResult.tierValue,
|
|
144
|
+
tierName: tierResult.tierName,
|
|
145
|
+
delta: densityResult.delta,
|
|
84
146
|
ambiguity: this._instance.aisp_ambig(docId),
|
|
85
|
-
errorCode:
|
|
147
|
+
errorCode: parseResult
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get detailed density breakdown for debugging
|
|
153
|
+
* @param {string} source - AISP source
|
|
154
|
+
* @returns {object} Detailed breakdown
|
|
155
|
+
*/
|
|
156
|
+
debug(source) {
|
|
157
|
+
const densityResult = calculateSemanticDensity(source);
|
|
158
|
+
const tierResult = getTierFromDelta(densityResult.delta);
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
...tierResult,
|
|
162
|
+
delta: densityResult.delta,
|
|
163
|
+
blockScore: densityResult.blockScore,
|
|
164
|
+
bindingScore: densityResult.bindingScore,
|
|
165
|
+
breakdown: densityResult.breakdown
|
|
86
166
|
};
|
|
87
167
|
},
|
|
88
168
|
|
|
@@ -130,8 +210,19 @@ const AISP = {
|
|
|
130
210
|
async validateFile(filePath) {
|
|
131
211
|
const content = await readFile(filePath, 'utf-8');
|
|
132
212
|
return this.validate(content);
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Debug file - show density breakdown
|
|
217
|
+
* @param {string} filePath - Path to AISP file
|
|
218
|
+
* @returns {Promise<object>} Debug breakdown
|
|
219
|
+
*/
|
|
220
|
+
async debugFile(filePath) {
|
|
221
|
+
const content = await readFile(filePath, 'utf-8');
|
|
222
|
+
return this.debug(content);
|
|
133
223
|
}
|
|
134
224
|
};
|
|
135
225
|
|
|
136
226
|
export default AISP;
|
|
137
|
-
export const { init, validate, isValid, getDensity, getTier, validateFile } = AISP;
|
|
227
|
+
export const { init, validate, isValid, getDensity, getTier, validateFile, debug, debugFile } = AISP;
|
|
228
|
+
export { calculateSemanticDensity, getTierFromDelta };
|