aboutsummaryrefslogtreecommitdiff
path: root/src/kompsos-collector.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/kompsos-collector.adb')
-rw-r--r--src/kompsos-collector.adb61
1 files changed, 41 insertions, 20 deletions
diff --git a/src/kompsos-collector.adb b/src/kompsos-collector.adb
index 2c52160..b8fc205 100644
--- a/src/kompsos-collector.adb
+++ b/src/kompsos-collector.adb
@@ -171,6 +171,7 @@ package body Kompsos.Collector is
return;
end if;
+ -- Delete cache
if Book.Cache /= null then
for Item of Book.Cache.Data loop
Free (Item.Data);
@@ -178,6 +179,7 @@ package body Kompsos.Collector is
Free (Book.Cache);
end if;
+ -- Delete all bookkeeping for lower nodes
case Book.Data.Kind is
when Unify_Node =>
Do_Reset (Ptr.Uni_Goal.Actual, Book.Next1, Extra);
@@ -195,6 +197,7 @@ package body Kompsos.Collector is
Do_Reset (Ptr.Rec_Goal.Actual, Book.Next1, Extra);
end case;
+ -- Set aside common nodes to be deleted later
if Ptr.Counter > 1 then
if not Extra.Contains (Book) then
Extra.Append (Book);
@@ -212,7 +215,10 @@ package body Kompsos.Collector is
Extra : Book_Node_Vectors.Vector;
begin
Do_Reset (Ptr, Book, Extra);
+
+ -- Handle common nodes
for Item of Extra loop
+ -- Ensure that Book doesn't end up dangling
if Item = Book then
Free (Book);
else
@@ -226,6 +232,8 @@ package body Kompsos.Collector is
(Kind : in Node_Kind)
return Book_Node_Access is
begin
+ -- This is needed because Ada does not allow declaring an object using
+ -- a discriminant that is not statically known.
case Kind is
when Unify_Node =>
return new Book_Node'(Data => (Kind => Unify_Node, others => <>), others => <>);
@@ -435,6 +443,9 @@ package body Kompsos.Collector is
Book.Next1 := Connect_Loose (Ptr.Rec_Goal.Actual);
end if;
if Ptr.Rec_Goal.Actual /= null then
+ -- Reach forwards to ensure the next node has cached results
+ -- even if it normally wouldn't have and that those results
+ -- are not discarded, so we can loop through them as needed.
if Book.Next1 = null then
Book.Next1 := New_Book (Ptr.Rec_Goal.Actual);
Book.Next1.Cache := new Cache_Entry'(True, State_Vectors.Empty_Vector);
@@ -476,7 +487,10 @@ package body Kompsos.Collector is
begin
if Ptr = null then
return False;
- elsif Ptr.Actual = null then
+ end if;
+
+ -- Lowest node in the graph always returns the Base State
+ if Ptr.Actual = null then
if Index = 1 then
Result := Base;
Use_New_Node := True;
@@ -484,9 +498,14 @@ package body Kompsos.Collector is
else
return False;
end if;
- elsif Book = null then
+ end if;
+
+ -- Attempt to connect common bookkeeping branches
+ if Book = null then
Book := Connect_Loose (Ptr.Actual);
end if;
+
+ -- If cached results exist, use those
if Book /= null and then Book.Cache /= null and then
Index <= Book.Cache.Data.Last_Index
then
@@ -497,25 +516,27 @@ package body Kompsos.Collector is
end if;
Use_New_Node := True;
return True;
- else
- return Found : constant Boolean :=
- Do_Get_Next (Ptr.Actual, Book, Base, Index, Result)
- do
- if Found then
- if Ptr.Actual.Counter > 1 and then
- Ptr.Actual /= Relation.Graph.Actual and then
- Book.Cache = null
- then
- Book.Cache := new Cache_Entry'(False, State_Vectors.Empty_Vector);
- end if;
- if Book.Cache /= null then
- pragma Assert (Index = Book.Cache.Data.Last_Index + 1);
- Book.Cache.Data.Append ((1, new State'(Result)));
- Use_New_Node := True;
- end if;
- end if;
- end return;
end if;
+
+ -- Otherwise, actual result calculation
+ return Found : constant Boolean :=
+ Do_Get_Next (Ptr.Actual, Book, Base, Index, Result)
+ do
+ if Found then
+ -- Cache results as needed
+ if Ptr.Actual.Counter > 1 and then
+ Ptr.Actual /= Relation.Graph.Actual and then
+ Book.Cache = null
+ then
+ Book.Cache := new Cache_Entry'(False, State_Vectors.Empty_Vector);
+ end if;
+ if Book.Cache /= null then
+ pragma Assert (Index = Book.Cache.Data.Last_Index + 1);
+ Book.Cache.Data.Append ((1, new State'(Result)));
+ Use_New_Node := True;
+ end if;
+ end if;
+ end return;
end Get_Next;