🕰️ Advanced Temporal Reasoning with TelaMentis
TelaMentis's bitemporal foundation (valid_time and transaction_time on TimeEdges) enables powerful temporal queries. Beyond basic "as-of" and "as-at" lookups, this document explores more advanced temporal reasoning patterns that can enhance AI agent capabilities.
1. Recap: Bitemporal Primitives
valid_from(VF): When a fact became true in the modeled world.valid_to(VT): When a fact ceased to be true (orNonefor ongoing). The interval[VF, VT)represents the valid duration.transaction_start_time(TS): When this version of the fact was recorded in the database.transaction_end_time(TE): When this version was superseded/logically deleted (Nonefor current version). The interval[TS, TE)represents database presence.
This guide primarily focuses on reasoning over valid_time, assuming queries operate on the current state of database knowledge (i.e., where TE is None).
2. Sequencing and Ordering
Determining the order of events or state changes.
- "Did event A happen before event B?"
- Requires identifying
TimeEdges representing A and B. - Compare
A.valid_fromandB.valid_from. - Example:
UserLoggedInEdge.valid_from < ItemPurchasedEdge.valid_from.
- Requires identifying
- "What was the sequence of status changes for Order X?"
- Query all
TimeEdges related to Order X's status (e.g.,Order--(HAS_STATUS {status: "value"})-->StatusConcept), order byvalid_from.
MATCH (o:Order {id: "X"})-[r:HAS_STATUS]->()
RETURN r.props.status, r.valid_from, r.valid_to
ORDER BY r.valid_from - Query all
3. Allen's Interval Algebra
Allen's Interval Algebra defines 13 basic relations between two time intervals (e.g., [A_VF, A_VT) and [B_VF, B_VT)). TelaMentis queries can be constructed to find these relationships.
Let interval A be [A_VF, A_VT) and interval B be [B_VF, B_VT). (A_VT or B_VT can be infinite/None).
- A
equalsB:A_VF = B_VF AND A_VT = B_VT - A
precedesB:A_VT < B_VF - A
meetsB:A_VT = B_VF - A
overlapsB:A_VF < B_VF AND A_VT > B_VF AND A_VT < B_VT - A
duringB:A_VF > B_VF AND A_VT < B_VT - A
startsB:A_VF = B_VF AND A_VT < B_VT - A
finishesB:A_VF > B_VF AND A_VT = B_VT(And their inverses:preceded_by,met_by,overlapped_by,contains,started_by,finished_by)
Example Query (A overlaps B for employment periods):
"Find employees whose employment at 'Acme' overlapped with their employment at 'BetaCorp'."
MATCH (p:Person)-[r_acme:EMPLOYED_AT]->(:Company {name: "Acme"}),
(p)-[r_beta:EMPLOYED_AT]->(:Company {name: "BetaCorp"})
WHERE r_acme.valid_from < r_beta.valid_from
AND r_acme.valid_to > r_beta.valid_from
AND r_acme.valid_to < r_beta.valid_to // Assuming valid_to is not null for closed periods
RETURN p.name, r_acme.valid_from AS acme_start, r_acme.valid_to AS acme_end,
r_beta.valid_from AS beta_start, r_beta.valid_to AS beta_end
4. Durations
Calculating how long a state persisted.
-
"How long was Project X in 'Active' status?"
- Find the TimeEdge for
ProjectX --(HAS_STATUS {status: "Active"})--> StatusConcept. - Duration =
edge.valid_to - edge.valid_from. (Requires date math functions, often provided by the database or calculated client-side). - If
valid_toisNone, duration is relative to "now".
MATCH (:Project {id: "X"})-[r:HAS_STATUS {status: "Active"}]->()
// Assuming valid_to is not null for this calculation, or we use 'now'
RETURN duration.between(r.valid_from, r.valid_to) AS active_duration
// 'duration.between' is a Neo4j function exampleNote: Handling NULL
valid_torequiresCOALESCE(r.valid_to, 'far_future_date')or specificIS NULLchecks. - Find the TimeEdge for
5. Temporal Aggregations
Counting or summarizing facts over time periods.
-
"How many users signed up each month in 2023?"
- Requires User nodes with a creation TimeEdge or a
CREATED_ATproperty that can be mapped tovalid_from. - Group by month extracted from
valid_from.
MATCH (u:User)-[r:WAS_CREATED]->() // Assuming a conceptual creation edge
WHERE r.valid_from >= date("2023-01-01") AND r.valid_from < date("2024-01-01")
RETURN r.valid_from.year AS year, r.valid_from.month AS month, count(u) AS signups
ORDER BY year, month - Requires User nodes with a creation TimeEdge or a
6. Detecting State Changes (Snapshots & Deltas)
Identifying when a specific property within an edge's props changed, or when an edge of a certain kind appeared/disappeared.
-
"When did User X's role change?"
- Query all
HAS_ROLEedges for User X, order byvalid_from. - Iterate through the sequence, comparing
props.roleof adjacent edges.
- Query all
-
"Show all versions of relationship R between Node A and Node B."
- Requires querying by
transaction_timeif you want to see how the database's record of that relationship evolved. - If only
valid_timeis considered, you see the evolution of the fact in the real world.
MATCH (a:Node {id: "A"})-[r:SOME_KIND]->(b:Node {id: "B"})
RETURN r.props, r.valid_from, r.valid_to //, r.transaction_start, r.transaction_end
ORDER BY r.valid_from // or r.transaction_start for DB history - Requires querying by
7. Temporal Trends and Patterns
Analyzing how data evolves over longer periods.
- "Show the evolution of average sentiment score for Topic Z over the last year, aggregated weekly."
- Requires Sentiment edges with scores and
valid_fromtimestamps. - Group by week, calculate average score.
- Requires Sentiment edges with scores and
- Identifying Co-occurring Temporal Patterns:
- "Do sales of Product A typically increase after marketing campaigns for Product A become active?"
- This involves finding
CampaignActiveintervals andSalesIncreaseintervals and checking for temporal relationships likestarts_after_start_oforoverlaps_with_end_of.
- This involves finding
- "Do sales of Product A typically increase after marketing campaigns for Product A become active?"
8. Point Events vs. Interval Events/States
- Point Events: Occurrences at a specific moment (e.g., "User Clicked Button").
- Model with
valid_from = valid_to = event_timestamp. - Or, create an Event node:
User --(PERFORMED_EVENT)--> ClickEvent {timestamp: T}.
- Model with
- Interval Events/States: Durations (e.g., "User Was Logged In").
- Model with
valid_from = start_time,valid_to = end_time(orNone).
- Model with
9. Challenges and Considerations
- Query Complexity: Advanced temporal queries can become complex. Encapsulate common patterns in helper functions or a DSL within TelaMentis or client libraries.
- Performance:
- Ensure
valid_fromandvalid_to(and transaction times) are well-indexed. Range indexes are essential. - Databases may have specialized temporal extensions or indexing strategies.
- Ensure
- Timezone Handling: Standardize on UTC for all timestamps within TelaMentis. Convert to local timezones only at the presentation/application layer.
- Clock Skew: Be aware of potential clock skew if timestamps originate from distributed sources. Use NTP.
- Defining "Now":
current_timestamp()can vary if a query runs for a long time. For consistency within a transaction, "now" should be fixed at the start.
10. Implications for AI Agent Memory
Advanced temporal reasoning allows agents to:
- Build Timelines: Construct chronological narratives of events and states.
- Understand Causality (Tentatively): Infer potential causal links by observing sequences and temporal overlaps (though true causality requires more than just temporal correlation).
- Predict Future States (Rudimentary): By analyzing past trends and patterns.
- Perform Counterfactual Reasoning (Conceptually): "What if event X had happened earlier?" (Requires more than just queries; involves simulation based on graph state at different times).
- Manage Long-Term Memory Coherence: Resolve conflicting information based on recency or specific validity periods.
By mastering these advanced temporal reasoning patterns, developers can build significantly more sophisticated and context-aware AI agents using TelaMentis.