(t *testing.T)
| 163 | } |
| 164 | |
| 165 | func TestTemporalEvaluator_WithVariable(t *testing.T) { |
| 166 | store := factstore.NewTemporalStore() |
| 167 | |
| 168 | // Add multiple employees with different active periods |
| 169 | store.Add(ast.NewAtom("active", name("/alice")), ast.TimeInterval( |
| 170 | ast.Date(2024, 1, 1), |
| 171 | ast.Date(2024, 1, 15), |
| 172 | )) |
| 173 | store.Add(ast.NewAtom("active", name("/bob")), ast.TimeInterval( |
| 174 | ast.Date(2024, 1, 10), |
| 175 | ast.Date(2024, 1, 25), |
| 176 | )) |
| 177 | store.Add(ast.NewAtom("active", name("/charlie")), ast.TimeInterval( |
| 178 | ast.Date(2023, 6, 1), |
| 179 | ast.Date(2023, 12, 31), |
| 180 | )) |
| 181 | |
| 182 | // Evaluation time: Jan 20, 2024 |
| 183 | evalTime := ast.Date(2024, 1, 20) |
| 184 | te := NewTemporalEvaluator(store, evalTime) |
| 185 | |
| 186 | // Query: <-[0d, 30d] active(X) - find who was active in last 30 days |
| 187 | queryAtom := ast.NewAtom("active", ast.Variable{Symbol: "X"}) |
| 188 | operator := ast.TemporalOperator{ |
| 189 | Type: ast.DiamondMinus, |
| 190 | Interval: ast.NewInterval( |
| 191 | ast.NewDurationBound(0), // ~0 days ago |
| 192 | ast.NewDurationBound(30*24*time.Hour), |
| 193 | ), |
| 194 | } |
| 195 | |
| 196 | tl := ast.TemporalLiteral{ |
| 197 | Literal: queryAtom, |
| 198 | Operator: &operator, |
| 199 | } |
| 200 | |
| 201 | solutions, err := te.EvalTemporalLiteral(tl, unionfind.New()) |
| 202 | if err != nil { |
| 203 | t.Fatalf("EvalTemporalLiteral error: %v", err) |
| 204 | } |
| 205 | |
| 206 | // Should find Alice, Bob, AND Charlie |
| 207 | // (Alice: Jan 1-15, Bob: Jan 10-25, Charlie: Jun-Dec 31 2023) |
| 208 | // At Jan 20, looking back 30 days (Dec 21 - Jan 20), all three overlap |
| 209 | if len(solutions) != 3 { |
| 210 | t.Errorf("Expected 3 solutions (Alice, Bob, and Charlie), got %d", len(solutions)) |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | func TestTemporalEvaluator_EternalFact(t *testing.T) { |
| 215 | store := factstore.NewTemporalStore() |
nothing calls this directly
no test coverage detected