-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with SLI;

separate (Sem)
procedure Wf_Basic_Declarative_Item
  (Node           : in     STree.SyntaxNode;
   Current_Scope  : in     Dictionary.Scopes;
   Component_Data : in out ComponentManager.ComponentData;
   The_Heap       : in out Heap.HeapRecord)
is
   Node_To_Check : STree.SyntaxNode;

   --------------------------------------------------------------------------

   procedure Check_Subtype_Against_Basetype_Bounds
     (Base_Type_Sym  : in     Dictionary.Symbol;
      Subtype_First  : in     LexTokenManager.Lex_String;
      Subtype_Last   : in     LexTokenManager.Lex_String;
      Ident_Node_Pos : in     LexTokenManager.Token_Position;
      Range_Node_Pos : in     LexTokenManager.Token_Position;
      Errors         : in out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     Dictionary.Dict;
   --#        in     LexTokenManager.State;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --# derives ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from Base_Type_Sym,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         Errors,
   --#                                         Ident_Node_Pos,
   --#                                         LexTokenManager.State,
   --#                                         Range_Node_Pos,
   --#                                         SPARK_IO.File_Sys,
   --#                                         Subtype_First,
   --#                                         Subtype_Last &
   --#         Errors                     from *,
   --#                                         Base_Type_Sym,
   --#                                         CommandLineData.Content,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Subtype_First,
   --#                                         Subtype_Last;
      is separate;

   -----------------------------------------------------------------------------------

   procedure Wf_Basic_Declaration
     (Node           : in     STree.SyntaxNode;
      Current_Scope  : in     Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      The_Heap       : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Component_Data,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.basic_declaration;
   --# post STree.Table = STree.Table~;
      is separate;

   --------------------------------------------------------------------------

   procedure Wf_Representation_Clause
     (Node          : in     STree.SyntaxNode;
      Current_Scope : in     Dictionary.Scopes;
      The_Heap      : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in out Aggregate_Stack.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Aggregate_Stack.State,
   --#         Dictionary.Dict,
   --#         LexTokenManager.State,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context,
   --#         SLI.State,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.representation_clause;
   --# post STree.Table = STree.Table~;
   is
      Location    : Dictionary.Location;
      Ident_Node  : STree.SyntaxNode;
      Subject_Str : LexTokenManager.Lex_String;
      Subject_Sym : Dictionary.Symbol;

      procedure Process_Address_Clause
        (Node        : in STree.SyntaxNode;
         Subject_Str : in LexTokenManager.Lex_String;
         Subject_Sym : in Dictionary.Symbol)
      --# global in     CommandLineData.Content;
      --#        in     LexTokenManager.State;
      --#        in     STree.Table;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --# derives Dictionary.Dict            from *,
      --#                                         Subject_Sym &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         Subject_Str,
      --#                                         Subject_Sym;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.representation_clause;
      is
      begin
         if Dictionary.Is_Variable (Subject_Sym) then
            -- It's a variable...OK unless it's a mode-less own variable
            Dictionary.AddVariableAddressClause (Subject_Sym);
            if Dictionary.GetOwnVariableOrConstituentMode (Subject_Sym) = Dictionary.DefaultMode then
               ErrorHandler.Semantic_Warning (Err_Num  => 396,
                                              Position => Node_Position (Node => Node),
                                              Id_Str   => Subject_Str);
            end if;
         elsif Dictionary.Is_Constant (Subject_Sym) then
            -- A constant...issue a warning
            ErrorHandler.Semantic_Warning (Err_Num  => 351,
                                           Position => Node_Position (Node => Node),
                                           Id_Str   => Subject_Str);
         elsif not Dictionary.IsProgramUnit (Subject_Sym) then
            -- if it's not a variable, not a constant, and not a program
            -- unit, then it's illegal.
            ErrorHandler.Semantic_Error
              (Err_Num   => 255,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => LexTokenManager.Null_String);
         end if;
      end Process_Address_Clause;

      procedure Process_Size_Clause
        (Node          : in     STree.SyntaxNode;
         Current_Scope : in     Dictionary.Scopes;
         Subject_Str   : in     LexTokenManager.Lex_String;
         Subject_Sym   : in     Dictionary.Symbol;
         The_Heap      : in out Heap.HeapRecord)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in out Aggregate_Stack.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out LexTokenManager.State;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out Statistics.TableUsage;
      --#        in out STree.Table;
      --# derives Aggregate_Stack.State,
      --#         Dictionary.Dict,
      --#         LexTokenManager.State,
      --#         Statistics.TableUsage,
      --#         STree.Table,
      --#         The_Heap                   from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table,
      --#                                         Subject_Sym,
      --#                                         The_Heap &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SLI.State,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         Subject_Str,
      --#                                         Subject_Sym,
      --#                                         The_Heap &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         Subject_Sym,
      --#                                         The_Heap;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.representation_clause;
      --# post STree.Table = STree.Table~;
      is
         Unwanted_Seq          : SeqAlgebra.Seq;
         Unused_Component_Data : ComponentManager.ComponentData;
         Simple_Expression     : Exp_Record;
         Simp_Node             : STree.SyntaxNode;
         Value_Int             : Integer;
         Error                 : Maths.ErrorCode;
         Lex_Value             : LexTokenManager.Lex_String;
      begin
         if Dictionary.IsType (Subject_Sym) then
            Heap.Reset (The_Heap);
            SeqAlgebra.CreateSeq (The_Heap, Unwanted_Seq);
            ComponentManager.Initialise (Unused_Component_Data);
            Simp_Node := Next_Sibling (Current_Node => Child_Node (Current_Node => Child_Node (Current_Node => Node)));
            -- ASSUME Simp_Node = simple_expression
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Simp_Node) = SP_Symbols.simple_expression,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Simp_Node = simple_expression in Process_Size_Clause");
            --# accept Flow, 10, Unused_Component_Data, "Expected ineffective assignment";
            Walk_Expression_P.Walk_Expression
              (Exp_Node                => Simp_Node,
               Scope                   => Current_Scope,
               Type_Context            => Dictionary.GetUniversalIntegerType,
               Context_Requires_Static => True,
               Ref_Var                 => Unwanted_Seq,
               Result                  => Simple_Expression,
               Component_Data          => Unused_Component_Data,
               The_Heap                => The_Heap);
            --# end accept;
            SeqAlgebra.DisposeOfSeq (The_Heap, Unwanted_Seq);
            if Simple_Expression.Is_Static then
               if Dictionary.IsIntegerTypeMark (Simple_Expression.Type_Symbol, Current_Scope) then
                  if Simple_Expression.Value /= Maths.NoValue then
                     Maths.ValueToInteger (Simple_Expression.Value, Value_Int, Error);
                     if Error = Maths.NoError then
                        -- Size must not be negative
                        if Value_Int >= 0 then
                           if LexTokenManager.Lex_String_Case_Insensitive_Compare
                             (Lex_Str1 => LexTokenManager.Null_String,
                              Lex_Str2 => Dictionary.TypeSizeAttribute (Subject_Sym)) =
                             LexTokenManager.Str_Eq then
                              Maths.StorageRep (Simple_Expression.Value, Lex_Value);
                              Dictionary.AddTypeSizeAttribute (Subject_Sym, Lex_Value);
                              ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
                           else
                              ErrorHandler.Semantic_Error
                                (Err_Num   => 250,
                                 Reference => ErrorHandler.No_Reference,
                                 Position  => Node_Position (Node => Simp_Node),
                                 Id_Str    => Subject_Str);
                           end if;
                        else
                           ErrorHandler.Semantic_Error
                             (Err_Num   => 253,
                              Reference => ErrorHandler.No_Reference,
                              Position  => Node_Position (Node => Simp_Node),
                              Id_Str    => Subject_Str);
                        end if;
                     else
                        ErrorHandler.Semantic_Warning
                          (Err_Num  => 200,
                           Position => Node_Position (Node => Simp_Node),
                           Id_Str   => LexTokenManager.Null_String);
                     end if;
                  else
                     ErrorHandler.Semantic_Warning
                       (Err_Num  => 201,
                        Position => Node_Position (Node => Simp_Node),
                        Id_Str   => LexTokenManager.Null_String);
                  end if;
               else
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 251,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Simp_Node),
                     Id_Str    => Subject_Str);
               end if;
            else
               ErrorHandler.Semantic_Error
                 (Err_Num   => 252,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Simp_Node),
                  Id_Str    => Subject_Str);
            end if;
         elsif Dictionary.IsSubtype (Subject_Sym) then
            -- Size for a non-first subtype is not permitted
            ErrorHandler.Semantic_Error
              (Err_Num   => 254,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => Subject_Str);
         else
            -- Anything else, just warn - legality is left to the compiler.
            ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
         end if;
      end Process_Size_Clause;

      function Attribute_Identifier (Node : STree.SyntaxNode) return LexTokenManager.Lex_String
      --# global in STree.Table;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.representation_clause;
      is
         Current_Node : STree.SyntaxNode;
      begin
         Current_Node := Child_Node (Current_Node => Node);
         -- ASSUME Current_Node = attribute_definition_clause
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Current_Node) = SP_Symbols.attribute_definition_clause,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Current_Node = attribute_definition_clause in Attribute_Identifier");

         Current_Node :=
           Child_Node
           (Current_Node => Next_Sibling (Current_Node => Child_Node (Current_Node => Child_Node (Current_Node => Current_Node))));
         -- ASSUME Current_Node = attribute_ident
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Current_Node) = SP_Symbols.attribute_ident,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Current_Node = attribute_ident in Attribute_Identifier");
         return Node_Lex_String (Node => Current_Node);
      end Attribute_Identifier;

   begin -- Wf_Representation_Clause

      -- Currently checks only:
      -- (1) that the name of the type or object is declared and visible
      -- (2) if object is a variable and clause is an address then:
      --           (a) set HasAddressClause flag in Dictionary
      --           (b) issues warning if variable is NOT a stream
      -- (3) issues warning that rep clauses cannot be fully understood by Examiner
      -- (4) for enum and record reps calls Dict procedures to add locations to dict file

      Location :=
        Dictionary.Location'(Start_Position => Node_Position (Node => Node),
                             End_Position   => Node_Position (Node => Node));

      Ident_Node := Last_Child_Of (Start_Node => Node);
      -- ASSUME Ident_Node = identifier OR character_literal
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier
           or else Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.character_literal,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Ident_Node = identifier OR character_literal in Wf_Representation_Clause");
      Subject_Str := Node_Lex_String (Node => Ident_Node);
      Subject_Sym :=
        Dictionary.LookupItem
        (Name              => Subject_Str,
         Scope             => Current_Scope,
         Context           => Dictionary.ProgramContext,
         Full_Package_Name => False);
      if Dictionary.Is_Null_Symbol (Subject_Sym) then
         ErrorHandler.Semantic_Error
           (Err_Num   => 1,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => Ident_Node),
            Id_Str    => Subject_Str);
         ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
      else
         -- ASSUME Child_Node (Current_Node => Node) = attribute_definition_clause OR enumeration_representation_clause OR
         --                                            record_representation_clause OR at_clause
         case Syntax_Node_Type (Node => Child_Node (Current_Node => Node)) is
            when SP_Symbols.attribute_definition_clause =>
               -- ASSUME Child_Node (Current_Node => Node) = attribute_definition_clause
               if LexTokenManager.Lex_String_Case_Insensitive_Compare
                 (Lex_Str1 => Attribute_Identifier (Node => Node),
                  Lex_Str2 => LexTokenManager.Address_Token) =
                 LexTokenManager.Str_Eq then
                  case CommandLineData.Content.Language_Profile is
                     when CommandLineData.SPARK83 =>
                        ErrorHandler.Semantic_Error
                          (Err_Num   => 54,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Node),
                           Id_Str    => LexTokenManager.Address_Token);
                     when CommandLineData.SPARK95_Onwards =>
                        STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                                   Node => Ident_Node);
                        Process_Address_Clause (Node        => Node,
                                                Subject_Str => Subject_Str,
                                                Subject_Sym => Subject_Sym);
                  end case;
                  ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
               elsif LexTokenManager.Lex_String_Case_Insensitive_Compare
                 (Lex_Str1 => Attribute_Identifier (Node => Node),
                  Lex_Str2 => LexTokenManager.Size_Token) =
                 LexTokenManager.Str_Eq then
                  STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                             Node => Ident_Node);
                  Process_Size_Clause
                    (Node          => Node,
                     Current_Scope => Current_Scope,
                     Subject_Str   => Subject_Str,
                     Subject_Sym   => Subject_Sym,
                     The_Heap      => The_Heap);
               else
                  STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                             Node => Ident_Node);
                  ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
               end if;
            when SP_Symbols.at_clause =>
               -- ASSUME Child_Node (Current_Node => Node) = at_clause
               case CommandLineData.Content.Language_Profile is
                  when CommandLineData.SPARK83 =>
                     STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                                Node => Ident_Node);
                  when CommandLineData.SPARK95_Onwards =>
                     -- "at" clause obsolete in 95 onwards
                     ErrorHandler.Semantic_Warning
                       (Err_Num  => 310,
                        Position => Node_Position (Node => Node),
                        Id_Str   => LexTokenManager.Null_String);
               end case;
               Process_Address_Clause (Node        => Node,
                                       Subject_Str => Subject_Str,
                                       Subject_Sym => Subject_Sym);
               ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
            when SP_Symbols.record_representation_clause =>
               -- ASSUME Child_Node (Current_Node => Node) = record_representation_clause
               if Dictionary.IsRecordTypeMark (Subject_Sym, Current_Scope) then
                  STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                             Node => Ident_Node);
                  Dictionary.Add_Representation_Clause (The_Type => Subject_Sym,
                                                        Clause   => Location);
               else
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 38,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Ident_Node),
                     Id_Str    => LexTokenManager.Null_String);
               end if;
               ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
            when SP_Symbols.enumeration_representation_clause =>
               -- ASSUME Child_Node (Current_Node => Node) = enumeration_representation_clause
               if Dictionary.IsTypeMark (Subject_Sym) and then Dictionary.TypeIsEnumeration (Subject_Sym) then
                  STree.Set_Node_Lex_String (Sym  => Subject_Sym,
                                             Node => Ident_Node);
                  Dictionary.Add_Representation_Clause (The_Type => Subject_Sym,
                                                        Clause   => Location);
               else
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 38,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Ident_Node),
                     Id_Str    => LexTokenManager.Null_String);
               end if;
               ErrorHandler.Representation_Clause (Position => Node_Position (Node => Node));
            when others =>
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Child_Node (Current_Node => Node) = attribute_definition_clause OR " &
                    "enumeration_representation_clause OR record_representation_clause OR at_clause in Wf_Representation_Clause");
         end case;
      end if;
   end Wf_Representation_Clause;

   --------------------------------------------------------------------------

   procedure Wf_Basic_Proof_Declaration
     (Node           : in     STree.SyntaxNode;
      Current_Scope  : in     Dictionary.Scopes;
      Component_Data : in out ComponentManager.ComponentData;
      The_Heap       : in out Heap.HeapRecord)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.File_Heap;
   --#        in     ContextManager.Ops.Unit_Heap;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SLI.State;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out STree.Table;
   --# derives Component_Data,
   --#         Dictionary.Dict,
   --#         Statistics.TableUsage,
   --#         STree.Table,
   --#         The_Heap                   from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table,
   --#                                         The_Heap &
   --#         SLI.State                  from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         Component_Data,
   --#                                         ContextManager.Ops.File_Heap,
   --#                                         ContextManager.Ops.Unit_Heap,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SLI.State,
   --#                                         STree.Table,
   --#                                         The_Heap;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.basic_proof_declaration;
   --# post STree.Table = STree.Table~;
   is
      Declaration_Node, Ident_Node : STree.SyntaxNode;
      Ident_Str                    : LexTokenManager.Lex_String;
      Sym                          : Dictionary.Symbol;

      function More_Than_One_Own_Var_Announced (Sym   : Dictionary.Symbol;
                                                Scope : Dictionary.Scopes) return Boolean
      --# global in Dictionary.Dict;
      is
         It              : Dictionary.Iterator;
         Count           : Natural := 0;
         Current_Own_Var : Dictionary.Symbol;
      begin
         It := Dictionary.FirstOwnVariable (Dictionary.GetEnclosingPackage (Scope));
         while not Dictionary.IsNullIterator (It) loop
            Current_Own_Var := Dictionary.CurrentSymbol (It);
            if Dictionary.Types_Are_Equal
              (Left_Symbol        => Dictionary.GetType (Current_Own_Var),
               Right_Symbol       => Sym,
               Full_Range_Subtype => False)
              and then Count <= 2 then
               Count := Count + 1;
            end if;
            It := Dictionary.NextSymbol (It);
         end loop;
         return Count = 2;
      end More_Than_One_Own_Var_Announced;

      --------------------------------------------------------------------------

      procedure Wf_Base_Type_Assertion (Node          : in STree.SyntaxNode;
                                        Current_Scope : in Dictionary.Scopes)
      --# global in     CommandLineData.Content;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives Dictionary.Dict,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.base_type_assertion;
      --# post STree.Table = STree.Table~;
      is
         Name_Node, Type_Node, Attr_Node, Base_Type_Node : STree.SyntaxNode;
         Type_Str, Attr_Str, Base_Type_Str               : LexTokenManager.Lex_String;
         Type_Sym, Base_Type_Sym                         : Dictionary.Symbol;
         Errors                                          : Boolean := False;

         procedure Ck_Attr_Is_Base
           (Attr_Node : in     STree.SyntaxNode;
            Attr_Str  : in     LexTokenManager.Lex_String;
            Errors    : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from Attr_Node,
         --#                                         Attr_Str,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table &
         --#         Errors                     from *,
         --#                                         Attr_Str,
         --#                                         LexTokenManager.State;
         --# pre Syntax_Node_Type (Attr_Node, STree.Table) = SP_Symbols.attribute_ident;
         is
         begin
            -- check that the attribute asserted is in fact 'Base
            if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Attr_Str,
                                                                    Lex_Str2 => LexTokenManager.Base_Token) /=
              LexTokenManager.Str_Eq then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 789,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Attr_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Errors := True;
            end if;
         end Ck_Attr_Is_Base;

         procedure Ck_Is_Type
           (Base_Type_Node, Type_Node : in     STree.SyntaxNode;
            Base_Type_Sym, Type_Sym   : in     Dictionary.Symbol;
            Errors                    : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from Base_Type_Node,
         --#                                         Base_Type_Sym,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         Type_Node,
         --#                                         Type_Sym &
         --#         Errors                     from *,
         --#                                         Base_Type_Sym,
         --#                                         Dictionary.Dict,
         --#                                         Type_Sym;
         --# pre Syntax_Node_Type (Base_Type_Node, STree.Table) = SP_Symbols.identifier and
         --#   Syntax_Node_Type (Type_Node, STree.Table) = SP_Symbols.identifier;
         is
         begin
            -- check that the type and base type specified are both actually types
            if not Dictionary.IsType (Type_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 790,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Type_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Errors := True;
            end if;
            if not Dictionary.IsType (Base_Type_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 790,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Base_Type_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Errors := True;
            end if;
         end Ck_Is_Type;

         procedure Ck_Typing
           (Base_Type_Node          : in     STree.SyntaxNode;
            Base_Type_Sym, Type_Sym : in     Dictionary.Symbol;
            Current_Scope           : in     Dictionary.Scopes;
            Errors                  : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from Base_Type_Node,
         --#                                         Base_Type_Sym,
         --#                                         CommandLineData.Content,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         Type_Sym &
         --#         Errors                     from *,
         --#                                         Base_Type_Sym,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         Type_Sym;
         --# pre Syntax_Node_Type (Base_Type_Node, STree.Table) = SP_Symbols.identifier;
         is
         begin
            -- check that the types are either both signed integer, or both
            -- floating point.
            if not ((Dictionary.IsIntegerTypeMark (Type_Sym, Current_Scope)
                       and then Dictionary.IsIntegerTypeMark (Base_Type_Sym, Current_Scope))
                    or else (Dictionary.IsFloatingPointTypeMark (Type_Sym, Current_Scope)
                               and then Dictionary.IsFloatingPointTypeMark (Base_Type_Sym, Current_Scope))) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 792,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Base_Type_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Errors := True;
            end if;
         end Ck_Typing;

         procedure Ck_No_Existing_Base_Type
           (Type_Node : in     STree.SyntaxNode;
            Type_Sym  : in     Dictionary.Symbol;
            Errors    : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         Errors,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         Type_Node,
         --#                                         Type_Sym &
         --#         Errors                     from *,
         --#                                         Dictionary.Dict,
         --#                                         Type_Sym;
         --# pre Syntax_Node_Type (Type_Node, STree.Table) = SP_Symbols.identifier;
         is
         begin
            -- check that the assertion is not about a predefined type
            -- or one that already has a base type assertion; guarded by
            -- check on Errors to avoid bogus reports for bad types
            if not Errors
              and then Dictionary.IsType (Type_Sym)
              and then not Dictionary.Is_Null_Symbol (Dictionary.GetBaseType (Type_Sym)) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 796,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Type_Node),
                  Id_Str    => LexTokenManager.Null_String);
               Errors := True;
            end if;
         end Ck_No_Existing_Base_Type;

         procedure Ck_Predefined_Base_Type
           (Base_Type_Node : in     STree.SyntaxNode;
            Base_Type_Sym  : in     Dictionary.Symbol;
            Errors         : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from Base_Type_Node,
         --#                                         Base_Type_Sym,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table &
         --#         Errors                     from *,
         --#                                         Base_Type_Sym,
         --#                                         Dictionary.Dict;
         --# pre Syntax_Node_Type (Base_Type_Node, STree.Table) = SP_Symbols.identifier;
         is
         begin
            -- check that the base type specified is predefined
            if Dictionary.IsType (Base_Type_Sym) then
               if not Dictionary.Types_Are_Equal
                 (Left_Symbol        => Dictionary.GetBaseType (Base_Type_Sym),
                  Right_Symbol       => Base_Type_Sym,
                  Full_Range_Subtype => False) then
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 791,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Base_Type_Node),
                     Id_Str    => LexTokenManager.Null_String);
                  Errors := True;
               end if;
            end if;
         end Ck_Predefined_Base_Type;

         procedure Ck_Real_Accuracy
           (Base_Type_Node          : in     STree.SyntaxNode;
            Base_Type_Sym, Type_Sym : in     Dictionary.Symbol;
            Errors                  : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from Base_Type_Node,
         --#                                         Base_Type_Sym,
         --#                                         CommandLineData.Content,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         Errors,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         Type_Sym &
         --#         Errors                     from *,
         --#                                         Base_Type_Sym,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Type_Sym;
         --# pre Syntax_Node_Type (Base_Type_Node, STree.Table) = SP_Symbols.identifier;
         is
            Type_Accuracy, Base_Type_Accuracy                   : LexTokenManager.Lex_String;
            Type_Accuracy_Val, Base_Type_Accuracy_Val, Comp_Val : Maths.Value;
            Maths_Error                                         : Maths.ErrorCode;
         begin
            -- This test only relevant if the type is a real
            if not Errors and then Dictionary.TypeIsReal (Type_Sym) then
               Type_Accuracy      := Dictionary.GetScalarAttributeValue (False, LexTokenManager.Digits_Token, Type_Sym);
               Base_Type_Accuracy := Dictionary.GetScalarAttributeValue (False, LexTokenManager.Digits_Token, Base_Type_Sym);
               if LexTokenManager.Lex_String_Case_Insensitive_Compare
                 (Lex_Str1 => Base_Type_Accuracy,
                  Lex_Str2 => LexTokenManager.Null_String) =
                 LexTokenManager.Str_Eq then
                  -- we require that the base type have a defined accuracy
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 797,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Base_Type_Node),
                     Id_Str    => LexTokenManager.Null_String);
                  Errors := True;
               else
                  -- check that the accuracy of the base type is at least that of the type
                  Type_Accuracy_Val      := Maths.ValueRep (Type_Accuracy);
                  Base_Type_Accuracy_Val := Maths.ValueRep (Base_Type_Accuracy);
                  Maths.Lesser (Base_Type_Accuracy_Val, Type_Accuracy_Val, Comp_Val, Maths_Error);
                  if Comp_Val = Maths.TrueValue and then Maths_Error = Maths.NoError then
                     ErrorHandler.Semantic_Error
                       (Err_Num   => 798,
                        Reference => ErrorHandler.No_Reference,
                        Position  => Node_Position (Node => Base_Type_Node),
                        Id_Str    => LexTokenManager.Null_String);
                     Errors := True;
                  end if;
               end if;
            end if;
         end Ck_Real_Accuracy;

         procedure Ck_Scoping
           (Type_Node     : in     STree.SyntaxNode;
            Type_Sym      : in     Dictionary.Symbol;
            Current_Scope : in     Dictionary.Scopes;
            Errors        : in out Boolean)
         --# global in     CommandLineData.Content;
         --#        in     Dictionary.Dict;
         --#        in     LexTokenManager.State;
         --#        in     STree.Table;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --# derives ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         Errors,
         --#                                         LexTokenManager.State,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         Type_Node,
         --#                                         Type_Sym &
         --#         Errors                     from *,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         Type_Sym;
         --# pre Syntax_Node_Type (Type_Node, STree.Table) = SP_Symbols.identifier;
         is
            Type_Scope : Dictionary.Scopes;
         begin
            -- check that the type assertion occurs in the same scope
            -- as the declaration of the type, or the corresponding
            -- private scope (if the type is private)
            if not Errors then
               Type_Scope := Dictionary.GetScope (Type_Sym);
               if not (Type_Scope = Current_Scope
                         or else (Dictionary.Set_Visibility
                                    (The_Visibility => Dictionary.Privat,
                                     The_Unit       => Dictionary.GetRegion (Type_Scope)) =
                                    Current_Scope
                                    and then Dictionary.TypeIsPrivate (TheType => Type_Sym))) then
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 795,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Type_Node),
                     Id_Str    => LexTokenManager.Null_String);
                  Errors := True;
               end if;
            end if;
         end Ck_Scoping;

      begin -- Wf_Base_Type_Assertion
         Name_Node := Child_Node (Current_Node => Node);
         -- ASSUME Name_Node = dotted_simple_name
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Name_Node) = SP_Symbols.dotted_simple_name,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Name_Node = dotted_simple_name in Wf_Base_Type_Assertion");

         Type_Node := Child_Node (Current_Node => Name_Node);
         -- ASSUME Type_Node = dotted_simple_name OR identifier
         if Syntax_Node_Type (Node => Type_Node) = SP_Symbols.dotted_simple_name then
            -- ASSUME Type_Node = dotted_simple_name
            ErrorHandler.Semantic_Error
              (Err_Num   => 799,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Type_Node),
               Id_Str    => LexTokenManager.Null_String);
         elsif Syntax_Node_Type (Node => Type_Node) = SP_Symbols.identifier then
            -- ASSUME Type_Node = identifier
            Type_Str := Node_Lex_String (Node => Type_Node);
            Type_Sym :=
              Dictionary.LookupItem
              (Name              => Type_Str,
               Scope             => Current_Scope,
               Context           => Dictionary.ProgramContext,
               Full_Package_Name => False);

            Attr_Node := Next_Sibling (Current_Node => Name_Node);
            -- ASSUME Attr_Node = attribute_ident
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Attr_Node) = SP_Symbols.attribute_ident,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Attr_Node = attribute_ident in Wf_Base_Type_Assertion");
            Attr_Str := Node_Lex_String (Node => Attr_Node);

            Base_Type_Node := Next_Sibling (Current_Node => Attr_Node);
            -- ASSUME Base_Type_Node = identifier
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Base_Type_Node) = SP_Symbols.identifier,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Base_Type_Node = identifier in Wf_Base_Type_Assertion");
            Base_Type_Str := Node_Lex_String (Node => Base_Type_Node);
            Base_Type_Sym :=
              Dictionary.LookupItem
              (Name              => Base_Type_Str,
               Scope             => Current_Scope,
               Context           => Dictionary.ProgramContext,
               Full_Package_Name => False);

            -- perform static semantic checks
            Ck_Attr_Is_Base (Attr_Node => Attr_Node,
                             Attr_Str  => Attr_Str,
                             Errors    => Errors);
            Ck_Is_Type
              (Base_Type_Node => Base_Type_Node,
               Type_Node      => Type_Node,
               Base_Type_Sym  => Base_Type_Sym,
               Type_Sym       => Type_Sym,
               Errors         => Errors);
            Ck_Typing
              (Base_Type_Node => Base_Type_Node,
               Base_Type_Sym  => Base_Type_Sym,
               Type_Sym       => Type_Sym,
               Current_Scope  => Current_Scope,
               Errors         => Errors);
            Ck_No_Existing_Base_Type (Type_Node => Type_Node,
                                      Type_Sym  => Type_Sym,
                                      Errors    => Errors);
            Ck_Predefined_Base_Type (Base_Type_Node => Base_Type_Node,
                                     Base_Type_Sym  => Base_Type_Sym,
                                     Errors         => Errors);
            if not Errors then
               -- If something has gone wrong, then DON'T try to look
               -- up Type_Sym'First and Type_Sym'Last
               Check_Subtype_Against_Basetype_Bounds
                 (Base_Type_Sym  => Base_Type_Sym,
                  Subtype_First  => Dictionary.GetScalarAttributeValue (False, LexTokenManager.First_Token, Type_Sym),
                  Subtype_Last   => Dictionary.GetScalarAttributeValue (False, LexTokenManager.Last_Token, Type_Sym),
                  Ident_Node_Pos => Node_Position (Node => Base_Type_Node),
                  Range_Node_Pos => Node_Position (Node => Base_Type_Node),
                  Errors         => Errors);
            end if;
            Ck_Real_Accuracy
              (Base_Type_Node => Base_Type_Node,
               Base_Type_Sym  => Base_Type_Sym,
               Type_Sym       => Type_Sym,
               Errors         => Errors);
            Ck_Scoping (Type_Node     => Type_Node,
                        Type_Sym      => Type_Sym,
                        Current_Scope => Current_Scope,
                        Errors        => Errors);
            if not Errors then
               STree.Set_Node_Lex_String (Sym  => Type_Sym,
                                          Node => Type_Node);
               STree.Set_Node_Lex_String (Sym  => Base_Type_Sym,
                                          Node => Base_Type_Node);
               Dictionary.SetBaseType (Type_Sym, Base_Type_Sym);
            end if;
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Type_Node = dotted_simple_name OR identifier in Wf_Base_Type_Assertion");
         end if;
      end Wf_Base_Type_Assertion;

      --------------------------------------------------------------------------
      -- Process a clause of the form:
      --    --# assert A'Always_Valid;
      -- or --# assert A.B.C'Always_Valid;
      -- Where A is a variable, and B anc C are (sub) components.
      -- If successful, mark the Variable/SubComponent symbol as "MarkedValid"
      -- which will suppress the "representation might be invalid" warning,
      -- and cause the appropriate "in range" VCs to be generated.
      --------------------------------------------------------------------------
      procedure Wf_Always_Valid_Variable_Assertion
        (Node           : in     STree.SyntaxNode;
         Current_Scope  : in     Dictionary.Scopes;
         Component_Data : in out ComponentManager.ComponentData;
         The_Heap       : in out Heap.HeapRecord)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SPARK_IO.File_Sys;
      --#        in out Statistics.TableUsage;
      --#        in out STree.Table;
      --# derives Component_Data,
      --#         Dictionary.Dict,
      --#         Statistics.TableUsage,
      --#         STree.Table,
      --#         The_Heap                   from *,
      --#                                         CommandLineData.Content,
      --#                                         Component_Data,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table,
      --#                                         The_Heap &
      --#         ErrorHandler.Error_Context,
      --#         SPARK_IO.File_Sys          from CommandLineData.Content,
      --#                                         Component_Data,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table,
      --#                                         The_Heap;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.alwaysvalid_variable_assertion;
      --# post STree.Table = STree.Table~;
      is
         Name_Node                        : STree.SyntaxNode;
         Entire_Sym, Object_Sym, Type_Sym : Dictionary.Symbol;

         -------------------------------------------------------------------------
         -- Name_Node  - Node naming a variable, or a (sub) field of a variable
         -- Entire_Sym - Symbol of entire variable (ie, first identifer found)
         -- Object_Sym - Symbol of right most element (ie, the variable or
         --              subcomponent to be marked)
         --              == NullSymbol if anything goes wrong
         -------------------------------------------------------------------------
         procedure Process_Dotted_Simple_Name
           (Name_Node      : in     STree.SyntaxNode;
            Current_Scope  : in     Dictionary.Scopes;
            Component_Data : in out ComponentManager.ComponentData;
            The_Heap       : in out Heap.HeapRecord;
            Entire_Sym     :    out Dictionary.Symbol;
            Object_Sym     :    out Dictionary.Symbol)
         --# global in     CommandLineData.Content;
         --#        in     ContextManager.Ops.Unit_Stack;
         --#        in     LexTokenManager.State;
         --#        in out Dictionary.Dict;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out Statistics.TableUsage;
         --#        in out STree.Table;
         --# derives Component_Data,
         --#         Dictionary.Dict,
         --#         Statistics.TableUsage,
         --#         STree.Table,
         --#         The_Heap                   from *,
         --#                                         CommandLineData.Content,
         --#                                         Component_Data,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Name_Node,
         --#                                         STree.Table,
         --#                                         The_Heap &
         --#         Entire_Sym                 from CommandLineData.Content,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Name_Node,
         --#                                         STree.Table &
         --#         ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         Component_Data,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Name_Node,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table,
         --#                                         The_Heap &
         --#         Object_Sym                 from CommandLineData.Content,
         --#                                         Component_Data,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Name_Node,
         --#                                         STree.Table,
         --#                                         The_Heap;
         --# pre Syntax_Node_Type (Name_Node, STree.Table) = SP_Symbols.dotted_simple_name;
         --# post STree.Table = STree.Table~;
         is
            It                      : STree.Iterator;
            Id_Node                 : STree.SyntaxNode;
            Id_Str, Previous_Id_Str : LexTokenManager.Lex_String;
         begin
            -- the first node must be the entire variable
            Previous_Id_Str := LexTokenManager.Null_String;

            It      := Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                        From_Root    => Name_Node,
                                        In_Direction => STree.Down);
            Id_Node := Get_Node (It => It); -- must be the entire variable

            -- ASSUME Id_Node = identifier
            Id_Str     := Node_Lex_String (Node => Id_Node);
            Object_Sym :=
              Dictionary.LookupItem
              (Name              => Id_Str,
               Scope             => Current_Scope,
               Context           => Dictionary.ProofContext,
               Full_Package_Name => False);
            Entire_Sym := Object_Sym;
            loop
               --# assert STree.Table = STree.Table~;
               -- check that what we have so far (inc the first symbol) is valid
               if Dictionary.Is_Null_Symbol (Object_Sym) then
                  ErrorHandler.Semantic_Error2
                    (Err_Num   => 1,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Id_Node),
                     Id_Str1   => Id_Str,
                     Id_Str2   => Previous_Id_Str);
                  Object_Sym := Dictionary.NullSymbol;
                  exit;
               end if;
               STree.Set_Node_Lex_String (Sym  => Object_Sym,
                                          Node => Id_Node);
               -- get the next symbol, if there is one
               It := STree.NextNode (It);
               exit when STree.IsNull (It);

               Id_Node := Get_Node (It => It);
               -- ASSUME Id_Node = identifier
               Previous_Id_Str := Id_Str;
               Id_Str          := Node_Lex_String (Node => Id_Node);

               -- we have another symbol (field selector), thus the previous
               -- one must be the entire variable, or a subcomponent, and it
               -- must be of a record type

               if not (Dictionary.IsVariableOrSubcomponent (Object_Sym)
                         and then Dictionary.TypeIsRecord (Dictionary.GetType (Object_Sym))) then
                  ErrorHandler.Semantic_Error_Sym
                    (Err_Num   => 9,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Id_Node),
                     Sym       => Object_Sym,
                     Scope     => Current_Scope);
                  Object_Sym := Dictionary.NullSymbol;
                  exit;
               end if;

               -- We have a symbol that might be a subcomponent, before we can
               -- check that it is, we need to add the subcomponent to the enclosing
               -- record symbol, since they are not added unless/until they are
               -- needed

               Add_Record_Sub_Components
                 (Record_Var_Sym  => Object_Sym,
                  Record_Type_Sym => Dictionary.GetType (Object_Sym),
                  Component_Data  => Component_Data,
                  The_Heap        => The_Heap);

               -- check that the symbol is indeed a subcomponent
               Object_Sym :=
                 Dictionary.LookupSelectedItem
                 (Prefix   => Object_Sym,
                  Selector => Id_Str,
                  Scope    => Current_Scope,
                  Context  => Dictionary.ProofContext);

            end loop;
            -- return the innermost component symbol, since this is what
            -- will carry the valid mark
         end Process_Dotted_Simple_Name;

         -- Only one-dimensional arrays can be marked as always_valid.
         function Is_One_Dimensional_Array (Type_Sym : in Dictionary.Symbol;
                                            Scope    : in Dictionary.Scopes) return Boolean
         --# global in Dictionary.Dict;
         is
         begin
            return Dictionary.IsArrayTypeMark (Type_Sym, Scope) and then Dictionary.GetNumberOfDimensions (Type_Sym) = 1;
         end Is_One_Dimensional_Array;

         -- A suitable record type is a non-tagged and only
         -- contains scalar or array of scalar components.
         function Is_Suitable_Record_Type (Type_Sym : in Dictionary.Symbol;
                                           Scope    : in Dictionary.Scopes) return Boolean
         --# global in Dictionary.Dict;
         is
            Iterator      : Dictionary.Iterator;
            Rec_Comp_Type : Dictionary.Symbol;
            Suitable      : Boolean;
         begin
            if not Dictionary.Is_Null_Symbol (Type_Sym)
              and then Dictionary.TypeIsRecord (Type_Sym)
              and then not Dictionary.TypeIsTagged (Type_Sym) then
               Iterator := Dictionary.FirstRecordComponent (Type_Sym);
               Suitable := not Dictionary.IsNullIterator (Iterator);

               -- Iterate over the components ensuring that they are of a
               -- suitable type.  Exit the loop if an unsuitable one is found.
               while (not Dictionary.IsNullIterator (Iterator)) loop
                  Rec_Comp_Type := Dictionary.GetType (Dictionary.CurrentSymbol (Iterator));
                  if not (Dictionary.IsScalarTypeMark (Rec_Comp_Type, Scope)
                            or else (not (Is_One_Dimensional_Array (Rec_Comp_Type, Scope)
                                            and then not Dictionary.IsScalarTypeMark
                                            (Dictionary.GetArrayComponent (Rec_Comp_Type),
                                             Scope)))) then
                     exit;
                  end if;
                  Iterator := Dictionary.NextSymbol (Iterator);
               end loop;

               -- The record is suitable if the record has at least one component
               -- and all its components are of a suitable type in which case
               -- the loop exits with a NullIterator.
               Suitable := Suitable and Dictionary.IsNullIterator (Iterator);

            else
               Suitable := False;
            end if;

            return Suitable;
         end Is_Suitable_Record_Type;

         -- A suitable array type is one-dimensional and has components which
         -- are scalar or are a suitable record type.
         function Is_Suitable_Array_Type (Type_Sym : in Dictionary.Symbol;
                                          Scope    : in Dictionary.Scopes) return Boolean
         --# global in Dictionary.Dict;
         is
            Suitable     : Boolean;
            Element_Type : Dictionary.Symbol;
         begin
            if Is_One_Dimensional_Array (Type_Sym, Scope) then
               Element_Type := Dictionary.GetArrayComponent (Type_Sym);

               Suitable := Dictionary.IsScalarTypeMark (Element_Type, Scope)
                 or else Is_Suitable_Record_Type (Element_Type, Scope);
            else
               Suitable := False;
            end if;
            return Suitable;
         end Is_Suitable_Array_Type;

      begin -- Wf_Always_Valid_Variable_Assertion
         Name_Node := Child_Node (Current_Node => Node);
         -- ASSUME Name_Node = dotted_simple_name
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Name_Node) = SP_Symbols.dotted_simple_name,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Name_Node = dotted_simple_name in Wf_Always_Valid_Variable_Assertion");
         -- check that the attribute asserted is in fact 'Always_Valid
         if LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => Node_Lex_String (Node => Next_Sibling (Current_Node => Name_Node)),
            Lex_Str2 => LexTokenManager.Always_Valid_Token) /=
           LexTokenManager.Str_Eq then
            ErrorHandler.Semantic_Error
              (Err_Num   => 656,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Next_Sibling (Current_Node => Name_Node)),
               Id_Str    => LexTokenManager.Null_String);
         else
            -- parse the variable name, which might refer to a record
            -- subcomponent: eg. Entire_Sym.First.Second.Component_Sym
            -- Object_Sym == NullSymbol if anything goes wrong
            Process_Dotted_Simple_Name
              (Name_Node      => Name_Node,
               Current_Scope  => Current_Scope,
               Component_Data => Component_Data,
               The_Heap       => The_Heap,
               Entire_Sym     => Entire_Sym,
               Object_Sym     => Object_Sym);
            -- Check that we are referring ultimately to a variable
            if not Dictionary.Is_Null_Symbol (Object_Sym) and then not Dictionary.Is_Variable (Entire_Sym) then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 657,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Node),
                  Id_Str    => LexTokenManager.Null_String);
               Object_Sym := Dictionary.NullSymbol;
            end if;

            -- Check that the variable is declared in the same scope
            if not Dictionary.Is_Null_Symbol (Object_Sym) and then Dictionary.GetScope (Entire_Sym) /= Current_Scope then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 659,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Node),
                  Id_Str    => LexTokenManager.Null_String);
               Object_Sym := Dictionary.NullSymbol;
            end if;

            -- Check that the type of the object is appropriate.
            -- It must either be scalar, a one dimensional array of scalar
            -- componemts, a record with only scalar or array of scalar
            -- components, or an array of records satisfying the aforementioned
            -- constraints.
            if not Dictionary.Is_Null_Symbol (Object_Sym) then
               Type_Sym := Dictionary.GetType (Object_Sym);

               if not (Dictionary.IsScalarTypeMark (Type_Sym, Current_Scope)
                         or else Is_Suitable_Array_Type (Type_Sym, Current_Scope)
                         or else Is_Suitable_Record_Type (Type_Sym, Current_Scope)) then
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 658,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Name_Node),
                     Id_Str    => LexTokenManager.Null_String);
                  Object_Sym := Dictionary.NullSymbol;
               end if;
            end if;

            -- Should check that it is a mode in own variable...
            if not Dictionary.Is_Null_Symbol (Object_Sym)
              and then Dictionary.GetOwnVariableOrConstituentMode (Entire_Sym) /= Dictionary.InMode then
               ErrorHandler.Semantic_Error
                 (Err_Num   => 662,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Node),
                  Id_Str    => LexTokenManager.Null_String);
               Object_Sym := Dictionary.NullSymbol;
            end if;

            -- Check that this object has not been marked valid already
            -- and if not, then mark it. The object might be a variable,
            -- or a record subcomponent, and they must be dealt with separately.
            if not Dictionary.Is_Null_Symbol (Object_Sym) then
               if Dictionary.Is_Variable (Object_Sym) then
                  if not Dictionary.VariableIsMarkedValid (Object_Sym) then
                     Dictionary.SetVariableMarkedValid (Object_Sym, True);
                  else
                     ErrorHandler.Semantic_Error
                       (Err_Num   => 660,
                        Reference => ErrorHandler.No_Reference,
                        Position  => Node_Position (Node => Name_Node),
                        Id_Str    => LexTokenManager.Null_String);
                  end if;
               elsif Dictionary.IsSubcomponent (Object_Sym) then
                  if not Dictionary.SubcomponentIsMarkedValid (Object_Sym) then
                     Dictionary.SetSubcomponentMarkedValid (Object_Sym, True);
                  else
                     ErrorHandler.Semantic_Error
                       (Err_Num   => 660,
                        Reference => ErrorHandler.No_Reference,
                        Position  => Node_Position (Node => Name_Node),
                        Id_Str    => LexTokenManager.Null_String);
                  end if;
               else
                  SystemErrors.Fatal_Error
                    (Sys_Err => SystemErrors.Assertion_Failure,
                     Msg     => "Component must be a variable or a SubComponent");
               end if;
            end if;
         end if;
      end Wf_Always_Valid_Variable_Assertion;

      procedure Wf_Object_Assertion (Node          : in STree.SyntaxNode;
                                     Current_Scope : in Dictionary.Scopes)
      --# global in     CommandLineData.Content;
      --#        in     ContextManager.Ops.File_Heap;
      --#        in     ContextManager.Ops.Unit_Heap;
      --#        in     ContextManager.Ops.Unit_Stack;
      --#        in     LexTokenManager.State;
      --#        in out Dictionary.Dict;
      --#        in out ErrorHandler.Error_Context;
      --#        in out SLI.State;
      --#        in out SPARK_IO.File_Sys;
      --#        in out STree.Table;
      --# derives Dictionary.Dict,
      --#         STree.Table                from CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         STree.Table &
      --#         ErrorHandler.Error_Context from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         SLI.State                  from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SPARK_IO.File_Sys,
      --#                                         STree.Table &
      --#         SPARK_IO.File_Sys          from *,
      --#                                         CommandLineData.Content,
      --#                                         ContextManager.Ops.File_Heap,
      --#                                         ContextManager.Ops.Unit_Heap,
      --#                                         ContextManager.Ops.Unit_Stack,
      --#                                         Current_Scope,
      --#                                         Dictionary.Dict,
      --#                                         ErrorHandler.Error_Context,
      --#                                         LexTokenManager.State,
      --#                                         Node,
      --#                                         SLI.State,
      --#                                         STree.Table;
      --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.object_assertion;
      --# post STree.Table = STree.Table~;
      is
         Ident_Node : STree.SyntaxNode;
         Ident_Str  : LexTokenManager.Lex_String;

         procedure Process_Simple_Name_Rep
           (Node          : in STree.SyntaxNode;
            Current_Scope : in Dictionary.Scopes;
            Rule_Policy   : in Dictionary.Rule_Policies)
         --# global in     CommandLineData.Content;
         --#        in     ContextManager.Ops.Unit_Stack;
         --#        in     LexTokenManager.State;
         --#        in out Dictionary.Dict;
         --#        in out ErrorHandler.Error_Context;
         --#        in out SPARK_IO.File_Sys;
         --#        in out STree.Table;
         --# derives Dictionary.Dict,
         --#         STree.Table                from CommandLineData.Content,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         LexTokenManager.State,
         --#                                         Node,
         --#                                         Rule_Policy,
         --#                                         STree.Table &
         --#         ErrorHandler.Error_Context,
         --#         SPARK_IO.File_Sys          from CommandLineData.Content,
         --#                                         ContextManager.Ops.Unit_Stack,
         --#                                         Current_Scope,
         --#                                         Dictionary.Dict,
         --#                                         ErrorHandler.Error_Context,
         --#                                         LexTokenManager.State,
         --#                                         Node,
         --#                                         Rule_Policy,
         --#                                         SPARK_IO.File_Sys,
         --#                                         STree.Table;
         --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.object_assertion;
         --# post STree.Table = STree.Table~;
         is
            It        : STree.Iterator;
            Next_Node : STree.SyntaxNode;

            procedure Process_Dotted_Simple_Name
              (Node          : in STree.SyntaxNode;
               Current_Scope : in Dictionary.Scopes;
               Rule_Policy   : in Dictionary.Rule_Policies)
            --# global in     CommandLineData.Content;
            --#        in     ContextManager.Ops.Unit_Stack;
            --#        in     LexTokenManager.State;
            --#        in out Dictionary.Dict;
            --#        in out ErrorHandler.Error_Context;
            --#        in out SPARK_IO.File_Sys;
            --#        in out STree.Table;
            --# derives Dictionary.Dict,
            --#         STree.Table                from CommandLineData.Content,
            --#                                         ContextManager.Ops.Unit_Stack,
            --#                                         Current_Scope,
            --#                                         Dictionary.Dict,
            --#                                         LexTokenManager.State,
            --#                                         Node,
            --#                                         Rule_Policy,
            --#                                         STree.Table &
            --#         ErrorHandler.Error_Context,
            --#         SPARK_IO.File_Sys          from CommandLineData.Content,
            --#                                         Current_Scope,
            --#                                         Dictionary.Dict,
            --#                                         ErrorHandler.Error_Context,
            --#                                         LexTokenManager.State,
            --#                                         Node,
            --#                                         SPARK_IO.File_Sys,
            --#                                         STree.Table;
            --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.dotted_simple_name;
            --# post STree.Table = STree.Table~;
            is
               Ident_Node, Next_Ident_Node             : STree.SyntaxNode;
               It                                      : STree.Iterator;
               Previous_Id_Str, Id_Str                 : LexTokenManager.Lex_String;
               Sym, SymSoFar, SymType, The_Rule_Policy : Dictionary.Symbol;
               PrefixOk                                : Boolean;
            begin
               It := Find_First_Node (Node_Kind    => SP_Symbols.identifier,
                                      From_Root    => Node,
                                      In_Direction => STree.Down);
               if not STree.IsNull (It => It) then
                  Ident_Node := Get_Node (It => It);
                  -- ASSUME Ident_Node = identifier
                  Id_Str          := Node_Lex_String (Node => Ident_Node);
                  Previous_Id_Str := LexTokenManager.Null_String;
                  Sym             :=
                    Dictionary.LookupItem
                    (Name              => Id_Str,
                     Scope             => Current_Scope,
                     Context           => Dictionary.ProofContext,
                     Full_Package_Name => False);
                  loop
                     --# assert STree.Table = STree.Table~ and
                     --#   Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
                     --#   Ident_Node = Get_Node (It);
                     if Dictionary.Is_Null_Symbol (Sym) then
                        ErrorHandler.Semantic_Error2
                          (Err_Num   => 1,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Node),
                           Id_Str1   => Id_Str,
                           Id_Str2   => Previous_Id_Str);
                        exit;
                     end if;
                     It              := STree.NextNode (It);
                     Next_Ident_Node := Get_Node (It => It);
                     -- ASSUME Next_Ident_Node = identifier OR NULL
                     if Dictionary.Is_Constant (Sym) then
                        SymType := Dictionary.GetType (Sym);
                        -- is constant, needs to be a composite constant
                        -- with no dotted part to right.
                        if Next_Ident_Node /= STree.NullNode then
                           ErrorHandler.Semantic_Error
                             (Err_Num   => 180,
                              Reference => ErrorHandler.No_Reference,
                              Position  => Node_Position (Node => Node),
                              Id_Str    => LexTokenManager.Null_String);
                           Sym := Dictionary.NullSymbol;
                        end if;
                        if not (Dictionary.TypeIsArray (SymType) or else Dictionary.TypeIsRecord (SymType)) then
                           ErrorHandler.Semantic_Error
                             (Err_Num   => 180,
                              Reference => ErrorHandler.No_Reference,
                              Position  => Node_Position (Node => Node),
                              Id_Str    => LexTokenManager.Null_String);
                           Sym := Dictionary.NullSymbol;
                        end if;
                        if not Dictionary.Is_Null_Symbol (Sym) then
                           STree.Set_Node_Lex_String (Sym  => Sym,
                                                      Node => Ident_Node);
                        end if;
                        exit;
                     end if;
                     if not Dictionary.IsPackage (Sym) then
                        ErrorHandler.Semantic_Error
                          (Err_Num   => 180,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Node),
                           Id_Str    => LexTokenManager.Null_String);
                        Sym := Dictionary.NullSymbol;
                        exit;
                     end if;
                     if Next_Ident_Node = STree.NullNode then
                        -- package without a selected component
                        ErrorHandler.Semantic_Error
                          (Err_Num   => 180,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Node),
                           Id_Str    => LexTokenManager.Null_String);
                        Sym := Dictionary.NullSymbol;
                        exit;
                     end if;
                     Check_Package_Prefix
                       (Node_Pos => Node_Position (Node => Ident_Node),
                        Pack_Sym => Sym,
                        Scope    => Current_Scope,
                        OK       => PrefixOk);
                     if not PrefixOk then
                        Sym := Dictionary.NullSymbol;
                        exit;
                     end if;
                     STree.Set_Node_Lex_String (Sym  => Sym,
                                                Node => Ident_Node);
                     Previous_Id_Str := Id_Str;
                     Ident_Node      := Next_Ident_Node;
                     -- ASSUME Ident_Node = identifier
                     Id_Str   := Node_Lex_String (Node => Ident_Node);
                     SymSoFar := Sym;
                     Sym      :=
                       Dictionary.LookupSelectedItem
                       (Prefix   => Sym,
                        Selector => Id_Str,
                        Scope    => Current_Scope,
                        Context  => Dictionary.ProofContext);
                     -- check to see if we are getting the same symbol over and again
                     if Sym = SymSoFar then -- P.P.P.P.X case
                        Sym := Dictionary.NullSymbol; -- to cause "Not visible" error at top of loop
                     end if;
                  end loop;
                  if not Dictionary.Is_Null_Symbol (Sym) then
                     if Dictionary.IsConstantRulePolicyPresent (Sym, Current_Scope) then
                        ErrorHandler.Semantic_Error2
                          (Err_Num   => 182,
                           Reference => ErrorHandler.No_Reference,
                           Position  => Node_Position (Node => Node),
                           Id_Str1   => Id_Str,
                           Id_Str2   => Previous_Id_Str);
                     else
                        Dictionary.AddConstantRulePolicy
                          (TheConstant   => Sym,
                           Comp_Unit     => ContextManager.Ops.Current_Unit,
                           Declaration   => Dictionary.Location'(Start_Position => Node_Position (Node => Ident_Node),
                                                                 End_Position   => Node_Position (Node => Ident_Node)),
                           TheScope      => Current_Scope,
                           ThePolicy     => Rule_Policy,
                           TheRulePolicy => The_Rule_Policy);
                        STree.Add_Node_Symbol (Node => Ident_Node,
                                               Sym  => The_Rule_Policy);
                     end if;
                  end if;
               end if;
            end Process_Dotted_Simple_Name;

         begin -- Process_Simple_Name_Rep
            It :=
              Find_First_Node
              (Node_Kind    => SP_Symbols.dotted_simple_name,
               From_Root    => Child_Node (Current_Node => Node),
               In_Direction => STree.Down);
            while not STree.IsNull (It) loop
               -- for each identifier in list of constants
               Next_Node := Get_Node (It => It);
               --# assert Syntax_Node_Type (Next_Node, STree.Table) = SP_Symbols.dotted_simple_name and
               --#   Next_Node = Get_Node (It) and
               --#   STree.Table = STree.Table~;
               Process_Dotted_Simple_Name (Node          => Next_Node,
                                           Current_Scope => Current_Scope,
                                           Rule_Policy   => Rule_Policy);
               It := STree.NextNode (It);
            end loop;
         end Process_Simple_Name_Rep;

      begin -- Wf_Object_Assertion
         Ident_Node := Next_Sibling (Current_Node => Child_Node (Current_Node => Node));
         -- ASSUME Ident_Node = identifier
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Ident_Node = identifier in Wf_Object_Assertion");
         Ident_Str := Node_Lex_String (Node => Ident_Node);
         if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Ident_Str,
                                                                 Lex_Str2 => LexTokenManager.Rule_Token) =
           LexTokenManager.Str_Eq then
            Process_Simple_Name_Rep (Node          => Node,
                                     Current_Scope => Current_Scope,
                                     Rule_Policy   => Dictionary.Rule_Requested);
         elsif LexTokenManager.Lex_String_Case_Insensitive_Compare
           (Lex_Str1 => Ident_Str,
            Lex_Str2 => LexTokenManager.No_Rule_Token) =
           LexTokenManager.Str_Eq then
            Process_Simple_Name_Rep (Node          => Node,
                                     Current_Scope => Current_Scope,
                                     Rule_Policy   => Dictionary.No_Rule_Requested);
         else
            -- Illegal proof rule switch
            ErrorHandler.Semantic_Error
              (Err_Num   => 181,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Ident_Node),
               Id_Str    => LexTokenManager.Null_String);
         end if;

         if ErrorHandler.Generate_SLI then
            SLI.Generate_Xref_Object_Assertion
              (Comp_Unit  => ContextManager.Ops.Current_Unit,
               Parse_Tree => Node,
               Scope      => Current_Scope);
         end if;
      end Wf_Object_Assertion;

   begin -- Wf_Basic_Proof_Declaration
      Declaration_Node := Child_Node (Current_Node => Node);
      -- ASSUME Declaration_Node = proof_type_declaration OR type_assertion OR object_assertion OR proof_constant_declaration
      case Syntax_Node_Type (Node => Declaration_Node) is
         when SP_Symbols.proof_type_declaration =>
            -- ASSUME Declaration_Node = proof_type_declaration
            Ident_Node := Child_Node (Current_Node => Declaration_Node);
            -- ASSUME Ident_Node = identifier
            SystemErrors.RT_Assert
              (C       => Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier,
               Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Ident_Node = identifier in Wf_Basic_Proof_Declaration");
            Ident_Str := Node_Lex_String (Node => Ident_Node);
            Sym       :=
              Dictionary.LookupItem
              (Name              => Ident_Str,
               Scope             => Current_Scope,
               Context           => Dictionary.ProofContext,
               Full_Package_Name => False);
            if Dictionary.Is_Null_Symbol (Sym)
              or else (Dictionary.IsTypeMark (Sym)
                         and then Dictionary.TypeIsAnnounced (TheType => Sym)
                         and then not Dictionary.Is_Declared (Item => Sym)) then
               -- it's ok to add because it either a new type or an announced type.
               -- unless more than one own variable has announced it
               if More_Than_One_Own_Var_Announced (Sym   => Sym,
                                                   Scope => Current_Scope) then
                  ErrorHandler.Semantic_Error
                    (Err_Num   => 149,
                     Reference => ErrorHandler.No_Reference,
                     Position  => Node_Position (Node => Ident_Node),
                     Id_Str    => Ident_Str);
               else -- still ok to add

                  -- Assumption warning: code assumes that proof type
                  -- is "abstract" because that is all the grammar
                  -- would permit at this point.  If we add fdl-based
                  -- proof types then more checks will be needed
                  -- here.
                  if not Dictionary.Is_Null_Symbol (Sym) then
                     STree.Set_Node_Lex_String (Sym  => Sym,
                                                Node => Ident_Node);
                  end if;
                  Dictionary.Add_Abstract_Proof_Type
                    (Name        => Ident_Str,
                     Comp_Unit   => ContextManager.Ops.Current_Unit,
                     Declaration => Dictionary.Location'(Start_Position => Node_Position (Node => Ident_Node),
                                                         End_Position   => Node_Position (Node => Ident_Node)),
                     Scope       => Current_Scope,
                     The_Type    => Sym);
                  STree.Add_Node_Symbol (Node => Ident_Node,
                                         Sym  => Sym);
                  if ErrorHandler.Generate_SLI then
                     SLI.Generate_Xref_Symbol
                       (Comp_Unit      => ContextManager.Ops.Current_Unit,
                        Parse_Tree     => Ident_Node,
                        Symbol         => Sym,
                        Is_Declaration => True);
                  end if;
               end if;
            else -- illegal duplicate
               ErrorHandler.Semantic_Error
                 (Err_Num   => 10,
                  Reference => ErrorHandler.No_Reference,
                  Position  => Node_Position (Node => Ident_Node),
                  Id_Str    => Ident_Str);
            end if;
         when SP_Symbols.type_assertion =>
            -- ASSUME Declaration_Node = type_assertion
            Declaration_Node := Child_Node (Current_Node => Declaration_Node);
            -- ASSUME Declaration_Node = base_type_assertion OR alwaysvalid_variable_assertion
            if Syntax_Node_Type (Node => Declaration_Node) = SP_Symbols.base_type_assertion then
               -- ASSUME Declaration_Node = base_type_assertion
               Wf_Base_Type_Assertion (Node          => Declaration_Node,
                                       Current_Scope => Current_Scope);
            elsif Syntax_Node_Type (Node => Declaration_Node) = SP_Symbols.alwaysvalid_variable_assertion then
               -- ASSUME Declaration_Node = alwaysvalid_variable_assertion
               Wf_Always_Valid_Variable_Assertion
                 (Node           => Declaration_Node,
                  Current_Scope  => Current_Scope,
                  Component_Data => Component_Data,
                  The_Heap       => The_Heap);
            else
               SystemErrors.Fatal_Error
                 (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
                  Msg     => "Expect Declaration_Node = base_type_assertion OR " &
                    "alwaysvalid_variable_assertion in Wf_Basic_Proof_Declaration");
            end if;
         when SP_Symbols.object_assertion =>
            -- ASSUME Declaration_Node = object_assertion
            Wf_Object_Assertion (Node          => Declaration_Node,
                                 Current_Scope => Current_Scope);
         when SP_Symbols.proof_constant_declaration =>
            -- ASSUME Declaration_Node = proof_constant_declaration
            ErrorHandler.Semantic_Error
              (Err_Num   => 315,
               Reference => ErrorHandler.No_Reference,
               Position  => Node_Position (Node => Node),
               Id_Str    => LexTokenManager.Null_String);
         when others =>
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Declaration_Node = proof_type_declaration OR type_assertion OR object_assertion OR " &
                 "proof_constant_declaration in Wf_Basic_Proof_Declaration");
      end case;
   end Wf_Basic_Proof_Declaration;

begin -- Wf_Basic_Declarative_Item
   Node_To_Check := Child_Node (Current_Node => Node);
   -- ASSUME Node_To_Check = basic_declaration OR justification_statement OR representation_clause OR basic_proof_declaration
   if Syntax_Node_Type (Node => Node_To_Check) = SP_Symbols.basic_declaration then
      -- ASSUME Node_To_Check = basic_declaration
      Wf_Basic_Declaration
        (Node           => Node_To_Check,
         Current_Scope  => Current_Scope,
         Component_Data => Component_Data,
         The_Heap       => The_Heap);
   elsif Syntax_Node_Type (Node => Node_To_Check) = SP_Symbols.representation_clause then
      -- ASSUME Node_To_Check = representation_clause
      Wf_Representation_Clause (Node          => Node_To_Check,
                                Current_Scope => Current_Scope,
                                The_Heap      => The_Heap);
   elsif Syntax_Node_Type (Node => Node_To_Check) = SP_Symbols.basic_proof_declaration then
      -- ASSUME Node_To_Check = basic_proof_declaration
      Wf_Basic_Proof_Declaration
        (Node           => Node_To_Check,
         Current_Scope  => Current_Scope,
         Component_Data => Component_Data,
         The_Heap       => The_Heap);
   elsif Syntax_Node_Type (Node => Node_To_Check) = SP_Symbols.justification_statement then
      -- ASSUME Node_To_Check = justification_statement
      Wf_Justification_Statement
        (Node           => Node_To_Check,
         Scope          => Current_Scope,
         Component_Data => Component_Data,
         The_Heap       => The_Heap);
   else
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Node_To_Check = basic_declaration OR justification_statement OR representation_clause OR " &
           "basic_proof_declaration in Wf_Basic_Declarative_Item");
   end if;
end Wf_Basic_Declarative_Item;
