diff options
Diffstat (limited to 'src/kompsos-collector.adb')
| -rw-r--r-- | src/kompsos-collector.adb | 61 |
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; |
