@@ -146,34 +146,52 @@ export function extractRules(atoms: readonly Atom[]): Array<[Atom, Atom]> {
146146 return out ;
147147}
148148
149- export function buildEnv ( atoms : Atom [ ] , gt : GroundingTable ) : MinEnv {
150- const rules = extractRules ( atoms ) ;
151- const ruleIndex = new Map < string , Array < [ Atom , Atom ] > > ( ) ;
152- const varRules : Array < [ Atom , Atom ] > = [ ] ;
153- for ( const [ lhs , rhs ] of rules ) {
149+ /** An empty environment for grounding table `gt`. Grow it with `addAtomToEnv`. */
150+ export function emptyEnv ( gt : GroundingTable ) : MinEnv {
151+ return {
152+ ruleIndex : new Map ( ) ,
153+ varRules : [ ] ,
154+ sigs : new Map ( ) ,
155+ gt,
156+ atoms : [ ] ,
157+ types : new Map ( ) ,
158+ imports : new Map ( ) ,
159+ exprTypes : [ ] ,
160+ } ;
161+ }
162+
163+ /** Incorporate one atom into `env` (mutating): rule index, signatures, types, and the atom list.
164+ * Lets a sequential runner extend the env per atom instead of rebuilding it each query (Phase-15
165+ * optimization; the 270/270 oracle gates it). */
166+ export function addAtomToEnv ( env : MinEnv , x : Atom ) : void {
167+ env . atoms . push ( x ) ;
168+ if ( opOf ( x ) === "=" && x . kind === "expr" && x . items . length === 3 ) {
169+ const lhs = x . items [ 1 ] ! ;
170+ const rhs = x . items [ 2 ] ! ;
154171 const k = headKey ( lhs ) ;
155- if ( k === undefined ) varRules . push ( [ lhs , rhs ] ) ;
172+ if ( k === undefined ) env . varRules . push ( [ lhs , rhs ] ) ;
156173 else {
157- const cur = ruleIndex . get ( k ) ?? [ ] ;
158- cur . push ( [ lhs , rhs ] ) ;
159- ruleIndex . set ( k , cur ) ;
174+ const cur = env . ruleIndex . get ( k ) ;
175+ if ( cur === undefined ) env . ruleIndex . set ( k , [ [ lhs , rhs ] ] ) ;
176+ else cur . push ( [ lhs , rhs ] ) ;
160177 }
161178 }
162- const sigs = new Map < string , Atom [ ] > ( ) ;
163- const types = new Map < string , Atom [ ] > ( ) ;
164- const exprTypes : Array < [ Atom , Atom ] > = [ ] ;
165- for ( const x of atoms ) {
166- if ( x . kind !== "expr" || opOf ( x ) !== ":" || x . items . length !== 3 ) continue ;
179+ if ( x . kind === "expr" && opOf ( x ) === ":" && x . items . length === 3 ) {
167180 const subj = x . items [ 1 ] ! ;
168181 const t = x . items [ 2 ] ! ;
169182 if ( subj . kind === "sym" ) {
170- if ( opOf ( t ) === "->" && t . kind === "expr" ) sigs . set ( subj . name , t . items . slice ( 1 ) ) ;
171- types . set ( subj . name , [ ...( types . get ( subj . name ) ?? [ ] ) , t ] ) ;
183+ if ( opOf ( t ) === "->" && t . kind === "expr" ) env . sigs . set ( subj . name , t . items . slice ( 1 ) ) ;
184+ env . types . set ( subj . name , [ ...( env . types . get ( subj . name ) ?? [ ] ) , t ] ) ;
172185 } else if ( subj . kind === "expr" ) {
173- exprTypes . push ( [ subj , t ] ) ;
186+ env . exprTypes . push ( [ subj , t ] ) ;
174187 }
175188 }
176- return { ruleIndex, varRules, sigs, gt, atoms, types, imports : new Map ( ) , exprTypes } ;
189+ }
190+
191+ export function buildEnv ( atoms : Atom [ ] , gt : GroundingTable ) : MinEnv {
192+ const env = emptyEnv ( gt ) ;
193+ for ( const x of atoms ) addAtomToEnv ( env , x ) ;
194+ return env ;
177195}
178196
179197function candidates ( env : MinEnv , toEval : Atom ) : Array < [ Atom , Atom ] > {
0 commit comments