summaryrefslogtreecommitdiff
path: root/src/kompsos-advanced_reify.adb
blob: 42df1e77fb7dfba662b63fdca30358086d35608e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147


--  Programmed by Jedidiah Barber
--  Licensed under the Sunset License v1.0

--  See license.txt for further details


package body Kompsos.Advanced_Reify is


    --  Term->Array Conversion  --

    function Flatten
           (Item : in Term)
        return Element_Array is
    begin
        case Item.Kind is
        when Null_Term =>
            return (1 => Null_Element);
        when Atom_Term =>
            return (1 => Item.Atom);
        when Var_Term =>
            return (1 => Variable_Convert (Item));
        when Pair_Term =>
            if Item.Right = Empty_Term then
                return Flatten (Item.Left);
            else
                return Flatten (Item.Left) & Flatten (Item.Right);
            end if;
        end case;
    end Flatten;



    --  Term->Tree Conversion  --

    function To_Tree
           (Item : in Term)
        return Element_Trees.Tree is
    begin
        return Result : Element_Trees.Tree := Element_Trees.Empty_Tree do
            case Item.Kind is
            when Null_Term =>
                Result.Append_Child (Result.Root, Null_Element);
            when Atom_Term =>
                Result.Append_Child (Result.Root, Item.Atom);
            when Var_Term =>
                Result.Append_Child (Result.Root, Variable_Convert (Item));
            when Pair_Term =>
                declare
                    The_Subtree : Element_Trees.Tree := To_Tree (Item.Left);
                    The_Place   : Element_Trees.Cursor;
                begin
                    if Item.Left.Kind = Pair_Term then
                        Result.Insert_Child
                           (Result.Root,
                            Element_Trees.No_Element,
                            Null_Element,
                            The_Place);
                    else
                        The_Place := Result.Root;
                    end if;
                    Result.Splice_Children
                       (The_Place,
                        Element_Trees.No_Element,
                        The_Subtree,
                        The_Subtree.Root);
                    if Item.Right /= Empty_Term then
                        The_Subtree := To_Tree (Item.Right);
                        Result.Splice_Children
                           (Result.Root,
                            Element_Trees.No_Element,
                            The_Subtree,
                            The_Subtree.Root);
                    end if;
                end;
            end case;
        end return;
    end To_Tree;



    --  Tree Reification  --

    function Treeify
           (Item  : in Term;
            Subst : in State)
        return Element_Trees.Tree is
    begin
        return To_Tree (Item.Resolve (Subst));
    end Treeify;


    function Treeify_First
           (Subst : in State)
        return Element_Trees.Tree is
    begin
        if Subst.LVars.Is_Empty then
            return Element_Trees.Empty_Tree;
        end if;
        for Iter in Subst.Ident.Iterate loop
            if ID_Number_Maps.Element (Iter) = Subst.LVars.First_Index then
                return Treeify (Term (T (Variable'(
                    Ident => ID_Number_Maps.Key (Iter),
                    Name  => Subst.LVars.Element (ID_Number_Maps.Element (Iter))))),
                    Subst);
            end if;
        end loop;
        return Element_Trees.Empty_Tree;
    end Treeify_First;


    function Treeify_First
           (Subst : in State;
            Name  : in String)
        return Element_Trees.Tree is
    begin
        return Treeify_First (Subst, +Name);
    end Treeify_First;


    function Treeify_First
           (Subst : in State;
            Name  : in Nametag)
        return Element_Trees.Tree
    is
        Name_Index : constant Name_Vectors.Extended_Index := Subst.LVars.Find_Index (Name);
    begin
        if Name_Index = Name_Vectors.No_Index then
            return Element_Trees.Empty_Tree;
        end if;
        for Iter in Subst.Ident.Iterate loop
            if ID_Number_Maps.Element (Iter) = Name_Index then
                return Treeify (Term (T (Variable'(
                    Ident => ID_Number_Maps.Key (Iter),
                    Name  => Subst.LVars.Element (ID_Number_Maps.Element (Iter))))),
                    Subst);
            end if;
        end loop;
        return Element_Trees.Empty_Tree;
    end Treeify_First;


end Kompsos.Advanced_Reify;