@@ -71,7 +71,7 @@ export interface ProposalProvider {
71
71
// Check if a prefix of solved variables is a valid potential solution
72
72
// for this provider. SolvingFor is used to ignore accept calls that
73
73
// aren't related to variables the provider is solving for.
74
- accept ( index : MultiIndex , prefix : any [ ] , solvingFor : Variable , force ?: boolean ) : boolean
74
+ accept ( index : MultiIndex , prefix : any [ ] , solvingFor : Variable , force ?: boolean , prejoin ?: boolean ) : boolean
75
75
}
76
76
77
77
//---------------------------------------------------------------------
@@ -497,8 +497,18 @@ export class NotScan {
497
497
propose ( ) { return ; }
498
498
resolveProposal ( ) { throw new Error ( "Resolving a not proposal" ) ; }
499
499
500
- accept ( multiIndex : MultiIndex , prefix , solvingFor , force ?) {
501
- if ( ! force && ! this . internalVars [ solvingFor . id ] && this . internalVars . length || ! fullyResolved ( this . args , prefix ) ) return true ;
500
+ accept ( multiIndex : MultiIndex , prefix , solvingFor , force ?, prejoin ?) {
501
+ // if we're in the prejoin phase and this not has no args, then we need
502
+ // to evaluate the not to see if we should run. If we didn't do this, arg-less
503
+ // nots won't get evaluated during Generic Join since we're never solving for a
504
+ // variable that this scan cares about.
505
+ if ( ( ! prejoin || this . args . length )
506
+ // if we aren't forcing and not solving for the current variable, then we just accept
507
+ // as it is
508
+ && ( ! force && ! this . internalVars [ solvingFor . id ] && this . internalVars . length )
509
+ // we also blind accept if we have args that haven't been filled in yet, as we don't
510
+ // have the dependencies necessary to make a decision
511
+ || ! fullyResolved ( this . args , prefix ) ) return true ;
502
512
let resolved = this . resolve ( prefix ) ;
503
513
let notPrefix = [ ] ;
504
514
let ix = 0 ;
@@ -825,13 +835,22 @@ function preJoinAccept(multiIndex: MultiIndex, providers : ProposalProvider[], v
825
835
if ( value !== undefined && vars [ ix ] !== undefined ) {
826
836
presolved ++ ;
827
837
for ( let provider of providers ) {
828
- if ( ! provider . accept ( multiIndex , prefix , solvingFor ) ) {
838
+ if ( ! provider . accept ( multiIndex , prefix , solvingFor , false , true ) ) {
829
839
return { accepted : false , presolved} ;
830
840
}
831
841
}
832
842
}
833
843
ix ++ ;
834
844
}
845
+ // we still need to do a single prejoin pass to make sure that any nots
846
+ // that may have no external dependencies are given a chance to end this
847
+ // evaluation
848
+ let fakeVar = new Variable ( 0 ) ;
849
+ for ( let provider of providers ) {
850
+ if ( provider instanceof NotScan && ! provider . accept ( multiIndex , prefix , fakeVar , false , true ) ) {
851
+ return { accepted : false , presolved} ;
852
+ }
853
+ }
835
854
return { accepted : true , presolved} ;
836
855
}
837
856
0 commit comments