-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.py
More file actions
54 lines (48 loc) · 1.9 KB
/
Copy pathclient.py
File metadata and controls
54 lines (48 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import datetime
from typing import Dict, Any, List, Optional
class TemporalKnowledgeGraphEdgeValidity:
"""
Manages knowledge graph relationships with bitemporal intervals (valid_from, valid_to).
Automatically retires outdated facts when contradictory relationships are asserted.
"""
def __init__(self):
self.edges: List[Dict[str, Any]] = []
def assert_fact(
self,
subject: str,
predicate: str,
obj: str,
valid_from: str,
valid_to: Optional[str] = None
) -> Dict[str, Any]:
# Expire any conflicting existing active edge with same subject & predicate
retired_count = 0
for edge in self.edges:
if edge["subject"] == subject and edge["predicate"] == predicate and edge["valid_to"] is None:
edge["valid_to"] = valid_from
retired_count += 1
new_edge = {
"edge_id": f"edge_{len(self.edges) + 1:04d}",
"subject": subject,
"predicate": predicate,
"object": obj,
"valid_from": valid_from,
"valid_to": valid_to,
"recorded_at": datetime.date.today().isoformat()
}
self.edges.append(new_edge)
return {
"status": "ASSERTED",
"edge_id": new_edge["edge_id"],
"retired_previous_facts": retired_count,
"new_fact": f"{subject} {predicate} {obj} [from: {valid_from}]"
}
def query_point_in_time(self, query_date: str) -> List[Dict[str, Any]]:
q_dt = datetime.date.fromisoformat(query_date)
active = []
for edge in self.edges:
vf = datetime.date.fromisoformat(edge["valid_from"])
vt = datetime.date.fromisoformat(edge["valid_to"]) if edge["valid_to"] else None
if vf <= q_dt and (vt is None or q_dt < vt):
active.append(edge)
return active