MCPcopy
hub / github.com/google/mangle / evalTemporalAtomWithoutOperator

Method evalTemporalAtomWithoutOperator

engine/temporal.go:83–156  ·  view source on GitHub ↗

evalTemporalAtomWithoutOperator looks up facts and optionally binds/filters by interval.

(
	atom ast.Atom,
	interval *ast.Interval,
	subst unionfind.UnionFind,
)

Source from the content-addressed store, hash-verified

81
82// evalTemporalAtomWithoutOperator looks up facts and optionally binds/filters by interval.
83func (te *TemporalEvaluator) evalTemporalAtomWithoutOperator(
84 atom ast.Atom,
85 interval *ast.Interval,
86 subst unionfind.UnionFind,
87) ([]unionfind.UnionFind, error) {
88 var solutions []unionfind.UnionFind
89
90 // Resolve the query interval if provided
91 var queryInterval ast.Interval
92 var hasConcreteInterval bool
93 var err error
94
95 if interval != nil {
96 // Try to resolve bounds to concrete timestamps
97 resolved, err := ResolveHeadTime(interval, subst, te.evaluationTime)
98 if err == nil && resolved != nil {
99 queryInterval = *resolved
100 hasConcreteInterval = true
101 } else {
102 // If we can't resolve (e.g. unbound variables), we'll filter after retrieval
103 // But for now, let's assume we fetch all and filter/bind
104 }
105 }
106
107 // Helper to process a fact
108 processFact := func(tf factstore.TemporalFact) error {
109 // Check if the fact is valid at current evaluation time (if no specific interval requested)
110 // OR if it satisfies the requested interval
111 if !hasConcreteInterval {
112 // Only filter by evaluation time if no interval was requested at all
113 if interval == nil && !tf.Interval.Contains(te.evaluationTime) {
114 return nil
115 }
116 } else {
117 // If we have a concrete query interval, what does it mean?
118 // foo(X)@[t1, t2] usually means we are looking for facts that cover this interval
119 // or are equal to it?
120 // DatalogMTL semantics usually imply:
121 // If interval is variable @[T], we bind T to the fact's interval.
122 // If interval is concrete @[t1, t2], we filter facts that COVER [t1, t2].
123 // Let's implement containment check: fact.Interval MUST CONTAIN queryInterval.
124 if !te.intervalContains(tf.Interval, queryInterval) {
125 return nil
126 }
127 }
128
129 // Unify the fact with the query atom
130 newSubst, err := unionfind.UnifyTermsExtend(atom.Args, tf.Atom.Args, subst)
131 if err != nil {
132 return nil // No match, continue
133 }
134
135 // Bind interval variables if present in the original query interval
136 if interval != nil {
137 newSubst = te.bindIntervalVariables(*interval, tf.Interval, newSubst)
138 }
139
140 solutions = append(solutions, newSubst)

Callers 1

EvalTemporalLiteralMethod · 0.95

Calls 7

intervalContainsMethod · 0.95
bindIntervalVariablesMethod · 0.95
UnifyTermsExtendFunction · 0.92
ResolveHeadTimeFunction · 0.85
ContainsMethod · 0.65
GetFactsDuringMethod · 0.65
GetAllFactsMethod · 0.65

Tested by

no test coverage detected