194 lines
4.8 KiB
Ada
194 lines
4.8 KiB
Ada
with Ada.Containers; use Ada.Containers;
|
|
|
|
with GNAT.IO;
|
|
|
|
package body Alire.Boolean_Trees is
|
|
|
|
----------
|
|
-- Leaf --
|
|
----------
|
|
|
|
function Leaf (C : Condition) return Tree is
|
|
begin
|
|
return T : Tree do
|
|
T.Append_Child (T.Root, Node'(Leaf, Conditions.To_Holder (C)));
|
|
end return;
|
|
end Leaf;
|
|
|
|
-----------------
|
|
-- Merge_Under --
|
|
-----------------
|
|
|
|
function Merge_Under (N : Node; L, R : Tree := Empty_Tree) return Tree is
|
|
use Trees;
|
|
begin
|
|
return T : Tree do
|
|
T.Append_Child (Parent => T.Root, New_Item => N);
|
|
|
|
declare
|
|
Op : constant Cursor := First_Child (T.Root);
|
|
begin
|
|
pragma Assert (Element (Op) = N);
|
|
|
|
if L /= Empty_Tree then
|
|
T.Copy_Subtree (Parent => Op,
|
|
Before => No_Element,
|
|
Source => First_Child (L.Root));
|
|
end if;
|
|
|
|
if R /= Empty_Tree then
|
|
T.Copy_Subtree (Parent => Op,
|
|
Before => No_Element,
|
|
Source => First_Child (R.Root));
|
|
end if;
|
|
end;
|
|
end return;
|
|
end Merge_Under;
|
|
|
|
-----------
|
|
-- "and" --
|
|
-----------
|
|
|
|
function "and" (L, R : Tree) return Tree is
|
|
begin
|
|
if L.Is_Empty and then R.Is_Empty then
|
|
return Empty_Tree;
|
|
elsif L.Is_Empty then
|
|
return R;
|
|
elsif R.Is_Empty then
|
|
return L;
|
|
else
|
|
return Merge_Under (Node'(Kind => And_Node), L, R);
|
|
end if;
|
|
end "and";
|
|
|
|
----------
|
|
-- "or" --
|
|
----------
|
|
|
|
function "or" (L, R : Tree) return Tree is
|
|
begin
|
|
if L.Is_Empty and then R.Is_Empty then
|
|
return Empty_Tree;
|
|
elsif L.Is_Empty then
|
|
return R;
|
|
elsif R.Is_Empty then
|
|
return L;
|
|
else
|
|
return Merge_Under (Node'(Kind => Or_Node), L, R);
|
|
end if;
|
|
end "or";
|
|
|
|
-----------
|
|
-- "not" --
|
|
-----------
|
|
|
|
function "not" (T : Tree) return Tree is
|
|
use Trees;
|
|
begin
|
|
return Merge_Under (Node'(Kind => Not_Node), T);
|
|
end "not";
|
|
|
|
-----------
|
|
-- Check --
|
|
-----------
|
|
|
|
function Check (T : Tree; V : Value; If_Empty : Boolean := True) return Boolean is
|
|
|
|
function Check (C : Trees.Cursor) return Boolean is
|
|
N : constant Node := Trees.Element (C);
|
|
begin
|
|
case N.Kind is
|
|
when Leaf =>
|
|
return Check (N.Condition.Element, V);
|
|
when And_Node =>
|
|
return Check (Trees.First_Child (C)) and then Check (Trees.Last_Child (C));
|
|
when Or_Node =>
|
|
return Check (Trees.First_Child (C)) or else Check (Trees.Last_Child (C));
|
|
when Not_Node =>
|
|
return not Check (Trees.First_Child (C));
|
|
end case;
|
|
end Check;
|
|
|
|
begin
|
|
if T.Is_Empty then
|
|
return If_Empty;
|
|
else
|
|
return Check (Trees.First_Child (T.Root));
|
|
end if;
|
|
end Check;
|
|
|
|
---------------------
|
|
-- Image_Recursive --
|
|
---------------------
|
|
|
|
function Image_Recursive (C : Trees.Cursor; Skeleton : Boolean) return String is
|
|
N : constant Node := Trees.Element (C);
|
|
begin
|
|
case N.Kind is
|
|
when Leaf =>
|
|
if Skeleton then
|
|
return "Leaf";
|
|
else
|
|
return Image (N.Condition.Constant_Reference);
|
|
end if;
|
|
when And_Node =>
|
|
return "(" & Image_Recursive (Trees.First_Child (C), Skeleton) & " and " &
|
|
Image_Recursive (Trees.Last_Child (C), Skeleton) & ")";
|
|
when Or_Node =>
|
|
return "(" & Image_Recursive (Trees.First_Child (C), Skeleton) & " or " &
|
|
Image_Recursive (Trees.Last_Child (C), Skeleton) & ")";
|
|
when Not_Node =>
|
|
return "(not " & Image_Recursive (Trees.First_Child (C), Skeleton) & ")";
|
|
end case;
|
|
end Image_Recursive;
|
|
|
|
-----------
|
|
-- Image --
|
|
-----------
|
|
|
|
function Image (T : Tree) return String is
|
|
use Trees;
|
|
begin
|
|
if T.Is_Empty then
|
|
return "(empty tree)";
|
|
else
|
|
return Image_Recursive (Trees.First_Child (T.Root), Skeleton => False);
|
|
end if;
|
|
end Image;
|
|
|
|
-----------
|
|
-- Print --
|
|
-----------
|
|
|
|
procedure Print (T : Tree) is
|
|
begin
|
|
GNAT.IO.Put_Line (T.Image);
|
|
end Print;
|
|
|
|
--------------------
|
|
-- Image_Skeleton --
|
|
--------------------
|
|
|
|
function Image_Skeleton (T : Tree) return String is
|
|
use Trees;
|
|
|
|
begin
|
|
if T.Is_Empty then
|
|
return "(empty tree)";
|
|
else
|
|
return Image_Recursive (Trees.First_Child (T.Root), Skeleton => True);
|
|
end if;
|
|
end Image_Skeleton;
|
|
|
|
--------------------
|
|
-- Print_Skeleton --
|
|
--------------------
|
|
|
|
procedure Print_Skeleton (T : Tree) is
|
|
begin
|
|
GNAT.IO.Put_Line (T.Image_Skeleton);
|
|
end Print_Skeleton;
|
|
|
|
end Alire.Boolean_Trees;
|