@hzhangxyz/ddss 0.0.40 → 0.0.41
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/README.md +6 -4
- package/dist/index.js +1 -1
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -24,7 +24,8 @@ The system consists of the following modules, implemented symmetrically in `ddss
|
|
|
24
24
|
- **Output** (`ddss/output.py`, `ddss/output.ts`): Real-time display of facts and ideas from the database
|
|
25
25
|
- **Load** (`ddss/load.py`, `ddss/load.ts`): Batch import of facts from standard input
|
|
26
26
|
- **Dump** (`ddss/dump.py`, `ddss/dump.ts`): Export all facts and ideas to output
|
|
27
|
-
- **
|
|
27
|
+
- **Search** (`ddss/search.py`, `ddss/search.ts`): Forward-chaining deductive search engine
|
|
28
|
+
- **Chain** (`ddss/chain.py`, `ddss/chain.ts`): Alternative forward-chaining engine using Chain API
|
|
28
29
|
- **Egg** (`ddss/egg.py`, `ddss/egg.ts`): E-graph based equality reasoning engine
|
|
29
30
|
|
|
30
31
|
## Installation
|
|
@@ -89,14 +90,14 @@ ddss --addr postgresql://user:password@host:port/database
|
|
|
89
90
|
|
|
90
91
|
### Selecting Components
|
|
91
92
|
|
|
92
|
-
By default, DDSS runs with all interactive components (`input`, `output`, `
|
|
93
|
+
By default, DDSS runs with all interactive components (`input`, `output`, `search`, `egg`). You can select specific components using the `-c` or `--component` option:
|
|
93
94
|
|
|
94
95
|
```bash
|
|
95
96
|
# Run only input and output (no inference engines)
|
|
96
97
|
ddss --component input output
|
|
97
98
|
|
|
98
99
|
# Run with only the forward-chaining engine
|
|
99
|
-
ddss --component input output
|
|
100
|
+
ddss --component input output search
|
|
100
101
|
|
|
101
102
|
# Run with only the E-graph engine
|
|
102
103
|
ddss --component input output egg
|
|
@@ -105,7 +106,8 @@ ddss --component input output egg
|
|
|
105
106
|
Available components:
|
|
106
107
|
- `input`: Interactive input interface
|
|
107
108
|
- `output`: Real-time display of facts and ideas
|
|
108
|
-
- `
|
|
109
|
+
- `search`: Forward-chaining deductive search engine
|
|
110
|
+
- `chain`: Alternative forward-chaining engine using Chain API
|
|
109
111
|
- `egg`: E-graph based equality reasoning engine
|
|
110
112
|
- `load`: Batch import facts from standard input
|
|
111
113
|
- `dump`: Export all facts and ideas to output
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import*as t from"node:fs/promises";import*as e from"node:os";import*as n from"node:path";import{Command as s}from"commander";import{Sequelize as o,DataTypes as i,Model as
|
|
2
|
+
import*as t from"node:fs/promises";import*as e from"node:os";import*as n from"node:path";import{Command as s}from"commander";import{Sequelize as o,DataTypes as i,Model as a,Op as r}from"sequelize";import{Search as c,Term as d,List as l,Rule as f,Chain as h}from"atsds";import{format as u}from"node:util";import{stdout as m,stdin as g}from"node:process";import{unparse as p,parse as w}from"atsds-bnf";import{EGraph as y}from"atsds-egg";import*as S from"node:readline/promises";class A extends a{}class x extends a{}async function q(t,e){await t.bulkCreate([{data:e}],{ignoreDuplicates:!0})}function M(t){if(!t.startsWith("--")){return`----\n${t.split("\n")[0]}\n`}return null}function v(t){return new f(`----\n${t.toString()}\n`)}function C(t){if(0!==t.length())return null;const e=t.conclusion().term();if(!(e instanceof l))return null;if(4!==e.length()||"binary"!==e.getitem(0).toString()||"=="!==e.getitem(1).toString())return null;return[e.getitem(2),e.getitem(3)]}function E(t,e){return new d(`(binary == ${t.toString()} ${e.toString()})`)}class b{core;mapping;constructor(){this.core=new y,this.mapping=new Map}getOrAdd(t){const e=t.toString();return this.mapping.has(e)||this.mapping.set(e,this.core.add(t)),this.mapping.get(e)}find(t){return this.core.find(this.getOrAdd(t))}setEquality(t,e){const n=this.getOrAdd(t),s=this.getOrAdd(e);this.core.merge(n,s)}getEquality(t,e){const n=this.getOrAdd(t),s=this.getOrAdd(e);return this.core.find(n)===this.core.find(s)}rebuild(){this.core.rebuild()}}class T{egraph;terms;facts;newlyAddedTerms;newlyAddedFacts;factMatchingCache;constructor(){this.egraph=new b,this.terms=new Set,this.facts=new Set,this.newlyAddedTerms=new Set,this.newlyAddedFacts=new Set,this.factMatchingCache=new Map}rebuild(){this.egraph.rebuild();const t=Array.from(this.newlyAddedTerms).map(t=>new d(t));for(const e of this.facts){const n=new d(e);this.factMatchingCache.has(e)||this.factMatchingCache.set(e,new Set);const s=this.collectMatchingCandidates(n,t);for(const t of s)this.factMatchingCache.get(e).add(t.toString())}const e=Array.from(this.terms).map(t=>new d(t));for(const t of this.newlyAddedFacts){const n=new d(t);this.factMatchingCache.has(t)||this.factMatchingCache.set(t,new Set);const s=this.collectMatchingCandidates(n,e);for(const e of s)this.factMatchingCache.get(t).add(e.toString())}this.newlyAddedTerms.clear(),this.newlyAddedFacts.clear()}add(t){this.addExpr(t),this.addFact(t)}addExpr(t){const e=C(t);if(!e)return;const[n,s]=e;this.terms.add(n.toString()),this.newlyAddedTerms.add(n.toString()),this.terms.add(s.toString()),this.newlyAddedTerms.add(s.toString()),this.egraph.setEquality(n,s)}addFact(t){if(0!==t.length())return;const e=t.conclusion();this.terms.add(e.toString()),this.newlyAddedTerms.add(e.toString()),this.facts.add(e.toString()),this.newlyAddedFacts.add(e.toString())}*execute(t){yield*this.executeExpr(t),yield*this.executeFact(t)}*executeExpr(t){const e=C(t);if(!e)return;const[n,s]=e;this.egraph.getEquality(n,s)&&(yield t);const o=Array.from(this.terms).map(t=>new d(t)),i=this.collectMatchingCandidates(n,o),a=this.collectMatchingCandidates(s,o);if(0===i.length||0===a.length)return;const r=this.groupByEquivalenceClass(i),c=this.groupByEquivalenceClass(a);for(const e of r)for(const n of c)if(e.size>0&&n.size>0){const s=new d(e.values().next().value),o=new d(n.values().next().value);if(this.egraph.getEquality(s,o))for(const s of e)for(const e of n){const n=E(new d(s),new d(e)),o=t.conclusion(),i=n.match(o);if(i){const t=n.ground(i,"1");t&&(yield v(t))}}}}*executeFact(t){if(0!==t.length())return;const e=t.conclusion();for(const n of this.facts)this.egraph.getEquality(e,new d(n))&&(yield t);const n=Array.from(this.terms).map(t=>new d(t)),s=this.collectMatchingCandidates(e,n);if(0===s.length)return;const o=this.groupByEquivalenceClass(s);for(const t of this.facts){const n=this.factMatchingCache.get(t);if(!n||0===n.size)continue;const s=Array.from(n).map(t=>new d(t)),i=this.groupByEquivalenceClass(s);for(const n of o)for(const s of i)if(n.size>0&&s.size>0){const o=new d(n.values().next().value),i=new d(s.values().next().value);if(this.egraph.getEquality(o,i))for(const o of n)for(const n of s){const s=E(new d(o),new d(n)),i=E(e,new d(t)),a=s.match(i);if(a){const t=s.ground(a,"1");if(t){const e=t.term();e instanceof l&&(yield v(e.getitem(2)))}}}}}}collectMatchingCandidates(t,e){return e.filter(e=>null!==t.match(e))}groupByEquivalenceClass(t){if(0===t.length)return[];const e=new Map;for(const n of t){const t=this.egraph.find(n).toString();e.has(t)||e.set(t,new Set),e.get(t).add(n.toString())}return Array.from(e.values())}}const $={search:async function(t){const e=new c;let n=-1;for(;;){const t=await A.findAll({where:{id:{[r.gt]:n}}});for(const s of t)n=Math.max(n,s.id),e.add(s.data);const s=[],o=t=>{const e=t.toString();s.push(q(A,e));const n=M(e);return n&&s.push(q(x,n)),!1};e.execute(o),await Promise.all(s),await new Promise(t=>setTimeout(t,0))}},egg:async function(t){const e=new T;let n=[],s=-1,o=-1;for(;;){const t=await x.findAll({where:{id:{[r.gt]:o}}});for(const e of t)o=Math.max(o,e.id),n.push(new f(e.data));const i=await A.findAll({where:{id:{[r.gt]:s}}});for(const t of i)s=Math.max(s,t.id),e.add(new f(t.data));e.rebuild();const a=[],c=[];for(const t of n){let n=!1;for(const s of e.execute(t))if(a.push(q(A,s.toString())),t.toString()===s.toString()){n=!0;break}n||c.push(t)}n=c,await Promise.all(a),await new Promise(t=>setTimeout(t,0))}},input:async function(t){const e=S.createInterface({input:g,output:m});e.setPrompt("input: ");const n=function(t){const e=m.write,n=console.log,s=console.error;let o=!1;return m.write=(n,s,i)=>{if(o)return e.call(m,n,s,i);if("\n"===n||"\r\n"===n)return e.call(m,n,s,i);if(n.includes("\n")){e.call(m,"\r");const a=e.call(m,n,s,i);return o=!0,t.prompt(),o=!1,a}return e.call(m,n,s,i)},console.log=(...t)=>{m.write(u(...t)+"\n")},console.error=(...t)=>{m.write(u(...t)+"\n")},()=>{m.write=e,console.log=n,console.error=s}}(e);e.prompt();for await(const t of e){const n=t.trim();if(""===n||n.startsWith("//"))e.prompt();else{try{const t=w(n);await q(A,t);const e=M(t);e&&await q(x,e)}catch(t){console.error(`error: ${t.message}`)}e.prompt()}}n(),e.close()},output:async function(t){let e=-1,n=-1;for(;;){const t=await x.findAll({where:{id:{[r.gt]:n}}});for(const e of t)n=Math.max(n,e.id),console.log("idea:",p(e.data));const s=await A.findAll({where:{id:{[r.gt]:e}}});for(const t of s)e=Math.max(e,t.id),console.log("fact:",p(t.data));await new Promise(t=>setTimeout(t,0))}},load:async function(t){const e=S.createInterface({input:g,terminal:!1});for await(const t of e){const e=t.trim();if(""!==e&&!e.startsWith("//"))try{const t=w(e);await q(A,t);const n=M(t);n&&await q(x,n)}catch(t){console.error(`error: ${t.message}`)}}e.close()},dump:async function(t){const e=await x.findAll();for(const t of e)console.log("idea:",p(t.data));const n=await A.findAll();for(const t of n)console.log("fact:",p(t.data))},chain:async function(t){const e=new h;let n=-1;for(;;){const t=await A.findAll({where:{id:{[r.gt]:n}}});for(const s of t)n=Math.max(n,s.id),e.add(s.data);const s=[],o=t=>{const e=t.toString();s.push(q(A,e));const n=M(e);return n&&s.push(q(x,n)),!1};e.execute(o),await Promise.all(s),await new Promise(t=>setTimeout(t,0))}}};async function F(t,e){const n=await async function(t){const e=new o(t,{logging:!1});return A.init({id:{type:i.INTEGER,primaryKey:!0,autoIncrement:!0},data:{type:i.TEXT,unique:!0,allowNull:!1}},{sequelize:e,tableName:"facts",timestamps:!1}),x.init({id:{type:i.INTEGER,primaryKey:!0,autoIncrement:!0},data:{type:i.TEXT,unique:!0,allowNull:!1}},{sequelize:e,tableName:"ideas",timestamps:!1}),await e.sync(),e}(t);for(const t of e)if(!(t in $))return void console.error(`error: unsupported component: ${t}`);const s=e.map(t=>(0,$[t])(n));await Promise.race(s),await n.close()}async function P(){const o=new s;o.name("ddss").description("DDSS - Distributed Deductive System Sorts: Run DDSS with an interactive deductive environment.").option("-a, --addr <url>","Database address URL. If not provided, uses a temporary SQLite database.").option("-c, --component <names...>","Components to run.",["input","output","search","egg"]).action(async s=>{let o,i=s.addr;if(!i){o=await t.mkdtemp(n.join(e.tmpdir(),"ddss-"));i=`sqlite:///${n.join(o,"ddss.db")}`}if(console.log(`addr: ${i}`),i.startsWith("sqlite://"))i=i.replace("sqlite:///","sqlite:");else if(i.startsWith("mysql://"));else if(i.startsWith("mariadb://"));else{if(!i.startsWith("postgresql://"))return void console.error(`error: unsupported database: ${i}`);i=i.replace("postgresql://","postgres://")}await F(i,s.component),o&&await t.rm(o,{recursive:!0,force:!0})}),o.parse()}import.meta.main&&P();export{P as cli};
|
package/package.json
CHANGED
|
@@ -22,30 +22,30 @@
|
|
|
22
22
|
"docs": "vitepress build"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"atsds": "^0.0.
|
|
26
|
-
"atsds-bnf": "^0.0.
|
|
27
|
-
"atsds-egg": "^0.0.
|
|
28
|
-
"commander": "^14.0.
|
|
29
|
-
"mariadb": "^3.
|
|
30
|
-
"mysql2": "^3.
|
|
31
|
-
"pg": "^8.
|
|
32
|
-
"sequelize": "^6.37.
|
|
25
|
+
"atsds": "^0.0.18",
|
|
26
|
+
"atsds-bnf": "^0.0.18",
|
|
27
|
+
"atsds-egg": "^0.0.18",
|
|
28
|
+
"commander": "^14.0.3",
|
|
29
|
+
"mariadb": "^3.5.2",
|
|
30
|
+
"mysql2": "^3.19.1",
|
|
31
|
+
"pg": "^8.20.0",
|
|
32
|
+
"sequelize": "^6.37.8",
|
|
33
33
|
"sqlite3": "^5.1.7"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@rollup/plugin-terser": "^0.
|
|
36
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
37
37
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
38
38
|
"@types/jest": "^30.0.0",
|
|
39
|
-
"@types/node": "^25.0
|
|
39
|
+
"@types/node": "^25.4.0",
|
|
40
40
|
"cross-env": "^10.1.0",
|
|
41
|
-
"jest": "^30.
|
|
41
|
+
"jest": "^30.3.0",
|
|
42
42
|
"npm-run-all": "^4.1.5",
|
|
43
|
-
"rollup": "^4.
|
|
43
|
+
"rollup": "^4.59.0",
|
|
44
44
|
"ts-jest": "^29.4.6",
|
|
45
45
|
"ts-node": "^10.9.2",
|
|
46
46
|
"tslib": "^2.8.1",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
48
|
"vitepress": "^1.6.4"
|
|
49
49
|
},
|
|
50
|
-
"version": "0.0.
|
|
50
|
+
"version": "0.0.41"
|
|
51
51
|
}
|