summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2025-11-15 16:06:40 +1300
committerJedidiah Barber <contact@jedbarber.id.au>2025-11-15 16:06:40 +1300
commit69514149fb1ddc17be744a883806e8bc3c8ebb7a (patch)
tree52ae7a59f4673145413e74b05fa80e9aafb6851b
parent72faae829a789664eedbda930cf815663c41c591 (diff)
Refactor of Terms that causes GNAT to STORAGE_ERROR
-rw-r--r--src/kompsos-pretty_print.adb22
-rw-r--r--src/kompsos-pretty_print.ads10
-rw-r--r--src/kompsos.adb203
-rw-r--r--src/kompsos.ads62
4 files changed, 132 insertions, 165 deletions
diff --git a/src/kompsos-pretty_print.adb b/src/kompsos-pretty_print.adb
index 7ecbb75..8739af8 100644
--- a/src/kompsos-pretty_print.adb
+++ b/src/kompsos-pretty_print.adb
@@ -62,25 +62,25 @@ package body Kompsos.Pretty_Print is
(Item : in Term)
return String is
begin
- case Item.Actual.Kind is
+ case Item.Kind is
+ when Null_Term =>
+ return "()";
when Atom_Term =>
- return Element_Image (Item.Actual.Value);
+ return Element_Image (Item.Atom);
when Var_Term =>
- return Image (Item.Actual.Refer);
+ return Image (Item.Var);
when Pair_Term =>
- if Item.Actual.Right.Actual = null then
- return Image (Item.Actual.Left);
- elsif Item.Actual.Right.Actual.Kind /= Pair_Term then
- return Image (Item.Actual.Left) & " . " & Bare (Item.Actual.Right);
+ if Item.Right.Kind = Null_Term then
+ return Image (Item.Left);
+ elsif Item.Right.Kind /= Pair_Term then
+ return Image (Item.Left) & " . " & Bare (Item.Right);
else
- return Image (Item.Actual.Left) & " " & Bare (Item.Actual.Right);
+ return Image (Item.Left) & " " & Bare (Item.Right);
end if;
end case;
end Bare;
begin
- if Item.Actual = null then
- return "()";
- elsif Item.Actual.Kind = Pair_Term then
+ if Item.Kind = Pair_Term then
return "(" & Bare (Item) & ")";
else
return Bare (Item);
diff --git a/src/kompsos-pretty_print.ads b/src/kompsos-pretty_print.ads
index ed9509a..bf0b9d7 100644
--- a/src/kompsos-pretty_print.ads
+++ b/src/kompsos-pretty_print.ads
@@ -14,6 +14,11 @@ package Kompsos.Pretty_Print is
function Image
+ (Item : in Variable)
+ return String;
+
+
+ function Image
(Item : in Term)
return String;
@@ -37,11 +42,6 @@ private
function Image
- (Item : in Variable)
- return String;
-
-
- function Image
(Item : in State)
return String;
diff --git a/src/kompsos.adb b/src/kompsos.adb
index c1d63da..22f0eb9 100644
--- a/src/kompsos.adb
+++ b/src/kompsos.adb
@@ -18,43 +18,6 @@ package body Kompsos is
-- Memory Management --
-------------------------
- -- Terms --
-
- procedure Free is new Ada.Unchecked_Deallocation (Term_Component, Term_Component_Access);
-
-
- procedure Initialize
- (This : in out Term) is
- begin
- -- For some reason, under some circumstances this is needed to ensure
- -- the access value is actually null. Not sure why.
- -- Seems to occur when constructing arrays with the & operator?
- This.Actual := null;
- end Initialize;
-
-
- procedure Adjust
- (This : in out Term) is
- begin
- if This.Actual /= null then
- This.Actual.Count := This.Actual.Count + 1;
- end if;
- end Adjust;
-
-
- procedure Finalize
- (This : in out Term) is
- begin
- if This.Actual /= null then
- This.Actual.Count := This.Actual.Count - 1;
- if This.Actual.Count = 0 then
- Free (This.Actual);
- end if;
- end if;
- end Finalize;
-
-
-
-- World_Holders --
procedure Free is new Ada.Unchecked_Deallocation (World'Class, World_Access);
@@ -107,40 +70,21 @@ package body Kompsos is
-- Terms --
- function "="
- (Left, Right : in Term)
- return Boolean is
+ function Kind
+ (This : in Term)
+ return Term_Kind is
begin
- if Left.Actual = null and Right.Actual = null then
- return True;
- end if;
- if Left.Actual = null or Right.Actual = null then
- return False;
- end if;
- if Left.Actual.Kind /= Right.Actual.Kind then
- return False;
- end if;
- case Left.Actual.Kind is
- when Atom_Term =>
- return Left.Actual.Value = Right.Actual.Value;
- when Var_Term =>
- return Left.Actual.Refer = Right.Actual.Refer;
- when Pair_Term =>
- return Left.Actual.Left = Right.Actual.Left and Left.Actual.Right = Right.Actual.Right;
- end case;
- end "=";
+ return Term_Component (This.Actual.Constant_Reference.Element.all).Kind;
+ end Kind;
function T
(Item : in Element_Type)
return Term is
begin
- return My_Term : Term do
- My_Term.Actual := new Term_Component'(
- Kind => Atom_Term,
- Count => 1,
- Value => Item);
- end return;
+ return (Actual => Term_Holders.To_Holder (Term_Component'(
+ Kind => Atom_Term,
+ Value => Item)));
end T;
@@ -148,12 +92,9 @@ package body Kompsos is
(Item : in Variable)
return Term is
begin
- return My_Term : Term do
- My_Term.Actual := new Term_Component'(
- Kind => Var_Term,
- Count => 1,
- Refer => Item);
- end return;
+ return (Actual => Term_Holders.To_Holder (Term_Component'(
+ Kind => Var_Term,
+ Refer => Item)));
end T;
@@ -161,13 +102,10 @@ package body Kompsos is
(Item1, Item2 : in Term'Class)
return Term is
begin
- return My_Term : Term do
- My_Term.Actual := new Term_Component'(
- Kind => Pair_Term,
- Count => 1,
- Left => Term (Item1),
- Right => Term (Item2));
- end return;
+ return (Actual => Term_Holders.To_Holder (Term_Component'(
+ Kind => Pair_Term,
+ Left => Term (Item1),
+ Right => Term (Item2))));
end T;
@@ -176,18 +114,45 @@ package body Kompsos is
return Term is
begin
if Items'Length = 0 then
- return My_Term : Term;
+ return Empty_Term;
+ else
+ return T (Items (Items'First), T (Items (Items'First + 1 .. Items'Last)));
end if;
- return My_Term : Term do
- My_Term.Actual := new Term_Component'(
- Kind => Pair_Term,
- Count => 1,
- Left => Items (Items'First),
- Right => T (Items (Items'First + 1 .. Items'Last)));
- end return;
end T;
+ function Atom
+ (This : in Term)
+ return Element_Type is
+ begin
+ return Term_Component (This.Actual.Constant_Reference.Element.all).Value;
+ end Atom;
+
+
+ function Var
+ (This : in Term)
+ return Variable is
+ begin
+ return Term_Component (This.Actual.Constant_Reference.Element.all).Refer;
+ end Var;
+
+
+ function Left
+ (This : in Term)
+ return Term is
+ begin
+ return Term_Component (This.Actual.Constant_Reference.Element.all).Left;
+ end Left;
+
+
+ function Right
+ (This : in Term)
+ return Term is
+ begin
+ return Term_Component (This.Actual.Constant_Reference.Element.all).Right;
+ end Right;
+
+
------------------------
@@ -213,17 +178,13 @@ package body Kompsos is
Item : in Term'Class)
return Boolean is
begin
- if Item.Actual = null then
- return True;
- end if;
- case Item.Actual.Kind is
- when Atom_Term =>
+ case Item.Kind is
+ when Null_Term | Atom_Term =>
return True;
when Var_Term =>
- return Has_Var (This, Item.Actual.Refer);
+ return Has_Var (This, Item.Var);
when Pair_Term =>
- return Fully_Contains (This, Item.Actual.Left) and then
- Fully_Contains (This, Item.Actual.Right);
+ return Fully_Contains (This, Item.Left) and then Fully_Contains (This, Item.Right);
end case;
end Fully_Contains;
@@ -233,11 +194,8 @@ package body Kompsos is
Item : in Term'Class)
return Term'Class is
begin
- if Item.Actual /= null and then
- Item.Actual.Kind = Var_Term and then
- This.Subst.Contains (Item.Actual.Refer.Ident)
- then
- return Walk (This, This.Subst.Constant_Reference (Item.Actual.Refer.Ident));
+ if Item.Kind = Var_Term and then This.Subst.Contains (Item.Var.Ident) then
+ return Walk (This, This.Subst.Constant_Reference (Item.Var.Ident));
else
return Item;
end if;
@@ -254,30 +212,30 @@ package body Kompsos is
Real_Right : Term'Class := Right;
begin
-- Resolve Variable substitution
- if Left.Actual /= null and then Left.Actual.Kind = Var_Term then
- if Has_Var (Potential, Left.Actual.Refer) then
+ if Left.Kind = Var_Term then
+ if Has_Var (Potential, Left.Var) then
Real_Left := Walk (Potential, Left);
else
return False;
end if;
end if;
- if Right.Actual /= null and then Right.Actual.Kind = Var_Term then
- if Has_Var (Potential, Right.Actual.Refer) then
+ if Right.Kind = Var_Term then
+ if Has_Var (Potential, Right.Var) then
Real_Right := Walk (Potential, Right);
else
return False;
end if;
end if;
- -- Check for equal null Terms
- if Real_Left.Actual = null and Real_Right.Actual = null then
+ -- Check for equal Null Terms
+ if Real_Left.Kind = Null_Term and Real_Right.Kind = Null_Term then
Extended := Potential;
return True;
end if;
-- Unify equal Variable Terms
- if Real_Left.Actual /= null and then Real_Left.Actual.Kind = Var_Term and then
- Real_Right.Actual /= null and then Real_Right.Actual.Kind = Var_Term and then
+ if Real_Left.Kind = Var_Term and then
+ Real_Right.Kind = Var_Term and then
Real_Left = Real_Right
then
Extended := Potential;
@@ -285,35 +243,30 @@ package body Kompsos is
end if;
-- Unify Variable and other Terms by introducing a new substitution
- if Real_Left.Actual /= null and then Real_Left.Actual.Kind = Var_Term then
- if Real_Right.Actual /= null and then Real_Right.Actual.Kind = Pair_Term and then
+ if Real_Left.Kind = Var_Term then
+ if Real_Right.Kind = Pair_Term and then
not Fully_Contains (Potential, Real_Right)
then
return False;
end if;
Extended := Potential;
- Extended.Subst.Insert (Real_Left.Actual.Refer.Ident, Term (Real_Right));
+ Extended.Subst.Insert (Real_Left.Var.Ident, Term (Real_Right));
return True;
end if;
- if Real_Right.Actual /= null and then Real_Right.Actual.Kind = Var_Term then
- if Real_Left.Actual /= null and then Real_Left.Actual.Kind = Pair_Term and then
+ if Real_Right.Kind = Var_Term then
+ if Real_Left.Kind = Pair_Term and then
not Fully_Contains (Potential, Real_Left)
then
return False;
end if;
Extended := Potential;
- Extended.Subst.Insert (Real_Right.Actual.Refer.Ident, Term (Real_Left));
+ Extended.Subst.Insert (Real_Right.Var.Ident, Term (Real_Left));
return True;
end if;
- -- Don't want any null terms beyond here
- if Real_Left.Actual = null or Real_Right.Actual = null then
- return False;
- end if;
-
-- Unify equal Atom Terms
- if Real_Left.Actual.Kind = Atom_Term and then
- Real_Right.Actual.Kind = Atom_Term and then
+ if Real_Left.Kind = Atom_Term and then
+ Real_Right.Kind = Atom_Term and then
Real_Left = Real_Right
then
Extended := Potential;
@@ -321,18 +274,16 @@ package body Kompsos is
end if;
-- Unify Pair Terms by unifying each corresponding part
- if Real_Left.Actual.Kind = Pair_Term and then
- Real_Right.Actual.Kind = Pair_Term and then
+ if Real_Left.Kind = Pair_Term and then
+ Real_Right.Kind = Pair_Term and then
Fully_Contains (Potential, Real_Left) and then
Fully_Contains (Potential, Real_Right)
then
declare
Middle : State;
begin
- return
- Do_Unify (Potential, Real_Left.Actual.Left, Real_Right.Actual.Left, Middle)
- and then
- Do_Unify (Middle, Real_Left.Actual.Right, Real_Right.Actual.Right, Extended);
+ return Do_Unify (Potential, Real_Left.Left, Real_Right.Left, Middle) and then
+ Do_Unify (Middle, Real_Left.Right, Real_Right.Right, Extended);
end;
end if;
@@ -927,7 +878,7 @@ package body Kompsos is
return World is
begin
return Result : World := This do
- Result.Unify (Null_Term, Nil_Term);
+ Result.Unify (Empty_Term, Nil_Term);
end return;
end Nil;
diff --git a/src/kompsos.ads b/src/kompsos.ads
index 0463f6f..37533be 100644
--- a/src/kompsos.ads
+++ b/src/kompsos.ads
@@ -27,14 +27,15 @@ package Kompsos is
-- Datatypes --
-----------------
+ type Variable is private;
+
+
+ type Term_Kind is (Null_Term, Atom_Term, Var_Term, Pair_Term);
+
type Term is tagged private;
type Term_Array is array (Positive range <>) of Term;
- Null_Term : constant Term;
-
- function "="
- (Left, Right : in Term)
- return Boolean;
+ Empty_Term : constant Term;
function T
(Item : in Element_Type)
@@ -48,7 +49,29 @@ package Kompsos is
(Items : in Term_Array)
return Term;
- -- Might include subprograms to retrieve Term contents later?
+ function Kind
+ (This : in Term)
+ return Term_Kind;
+
+ function Atom
+ (This : in Term)
+ return Element_Type
+ with Pre => This.Kind = Atom_Term;
+
+ function Var
+ (This : in Term)
+ return Variable
+ with Pre => This.Kind = Var_Term;
+
+ function Left
+ (This : in Term)
+ return Term
+ with Pre => This.Kind = Pair_Term;
+
+ function Right
+ (This : in Term)
+ return Term
+ with Pre => This.Kind = Pair_Term;
type World is tagged private;
@@ -392,11 +415,14 @@ private
- type Term_Kind is (Atom_Term, Var_Term, Pair_Term);
+ type Term_Root is abstract tagged null record;
- type Term_Component (Kind : Term_Kind) is record
- Count : Long_Integer;
+ package Term_Holders is new Ada.Containers.Indefinite_Holders (Term_Root'Class);
+
+ type Term_Component (Kind : Term_Kind) is new Term_Root with record
case Kind is
+ when Null_Term =>
+ null;
when Atom_Term =>
Value : Element_Type;
when Var_Term =>
@@ -406,22 +432,12 @@ private
end case;
end record;
- type Term_Component_Access is access Term_Component;
-
- type Term is new Ada.Finalization.Controlled with record
- Actual : Term_Component_Access;
+ type Term is tagged record
+ Actual : Term_Holders.Holder := Term_Holders.To_Holder (Term_Component'(Kind => Null_Term));
end record;
- overriding procedure Initialize
- (This : in out Term);
-
- overriding procedure Adjust
- (This : in out Term);
-
- overriding procedure Finalize
- (This : in out Term);
-
- Null_Term : constant Term := (Ada.Finalization.Controlled with Actual => null);
+ Empty_Term : constant Term :=
+ (Actual => Term_Holders.To_Holder (Term_Component'(Kind => Null_Term)));
package Term_Array_Holders is new Ada.Containers.Indefinite_Holders (Term_Array);