Files
alire-index-community/src/alire-boolean_trees.adb
T
2018-02-19 15:04:11 +01:00

133 lines
3.4 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
return Merge_Under (Node'(Kind => And_Node), L, R);
end "and";
----------
-- "or" --
----------
function "or" (L, R : Tree) return Tree is
begin
return Merge_Under (Node'(Kind => Or_Node), L, R);
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) 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
return Check (Trees.First_Child (T.Root));
end Check;
--------------------
-- Print_Skeleton --
--------------------
procedure Print_Skeleton (T : Tree) is
use GNAT.IO;
use Trees;
function Image (C : Trees.Cursor) return String is
N : constant Node := Trees.Element (C);
begin
case N.Kind is
when Leaf =>
return "Leaf";
when And_Node =>
return "(" & Image (Trees.First_Child (C)) & " and " & Image (Trees.Last_Child (C)) & ")";
when Or_Node =>
return "(" & Image (Trees.First_Child (C)) & " or " & Image (Trees.Last_Child (C)) & ")";
when Not_Node =>
return "(not " & Image (Trees.First_Child (C)) & ")";
end case;
end Image;
begin
if T.Is_Empty then
Put_Line ("(null tree)");
else
Put_Line (Image (Trees.First_Child (T.Root)));
end if;
end Print_Skeleton;
end Alire.Boolean_Trees;