evalBoxMinus implements the box-minus operator ([-). It returns true if the atom was true CONTINUOUSLY throughout the past interval. Syntax: [-[d1, d2] p(X) means "p(X) was true for the entire period from d2 ago to d1 ago"
( atom ast.Atom, opInterval ast.Interval, interval *ast.Interval, subst unionfind.UnionFind, )
| 201 | // It returns true if the atom was true CONTINUOUSLY throughout the past interval. |
| 202 | // Syntax: [-[d1, d2] p(X) means "p(X) was true for the entire period from d2 ago to d1 ago" |
| 203 | func (te *TemporalEvaluator) evalBoxMinus( |
| 204 | atom ast.Atom, |
| 205 | opInterval ast.Interval, |
| 206 | interval *ast.Interval, |
| 207 | subst unionfind.UnionFind, |
| 208 | ) ([]unionfind.UnionFind, error) { |
| 209 | // Calculate the query interval based on the operator's interval |
| 210 | queryInterval, err := te.resolveOperatorInterval(opInterval) |
| 211 | if err != nil { |
| 212 | return nil, err |
| 213 | } |
| 214 | |
| 215 | var solutions []unionfind.UnionFind |
| 216 | |
| 217 | // Query all facts matching the atom |
| 218 | err = te.temporalStore.GetAllFacts(atom, func(tf factstore.TemporalFact) error { |
| 219 | // Unify first to check if this fact matches |
| 220 | newSubst, err := unionfind.UnifyTermsExtend(atom.Args, tf.Atom.Args, subst) |
| 221 | if err != nil { |
| 222 | return nil // No match, continue |
| 223 | } |
| 224 | |
| 225 | // For box-minus, the fact's interval must CONTAIN the query interval |
| 226 | // (the fact must be true throughout the entire query period) |
| 227 | if te.intervalContains(tf.Interval, queryInterval) { |
| 228 | // Bind interval variables if present |
| 229 | if interval != nil { |
| 230 | newSubst = te.bindIntervalVariables(*interval, tf.Interval, newSubst) |
| 231 | } |
| 232 | |
| 233 | solutions = append(solutions, newSubst) |
| 234 | } |
| 235 | return nil |
| 236 | }) |
| 237 | |
| 238 | if err != nil { |
| 239 | return nil, err |
| 240 | } |
| 241 | |
| 242 | return solutions, nil |
| 243 | } |
| 244 | |
| 245 | // resolveOperatorInterval converts an operator interval (with durations) to absolute timestamps. |
| 246 | // For past operators, durations are interpreted as offsets from the evaluation time. |
no test coverage detected