21,176c21,176
< '*rule*'("variable_length",
<          @,
<          @) :- is_list_member("declaration",
<                               @), (parse_mode :== prefix, @ :== local_declaration), !, '*rule_name*' <<- ref("variable_length"), @ = @ .scope, @ = @ .left_brace, @ = @ .right_brace,(@ .file :\== @ .file, !, error_msg("Braces around a block must be in the same file",
<                                                                                                                                                                                                                          @) ; strlen(@ .name .id) =< sqrt(@ .line - @ .line), !, error_msg("Variable name is too short",
<                                                                                                                                                                                                                                                                                            @ .name) ; succeed) ; succeed.
< 
< '*rule*'("extern_in_c_file",
<          @,
<          @) :- is_list_member("declaration",
<                               @), (parse_mode :== prefix, @ :== external_declaration), !, '*rule_name*' <<- ref("extern_in_c_file"),((@ .type .store_class :== extern, file_extension(@ .name .file) :== "c"), !, error_msg("No declaration in a .c file accessed out of the .c file",
<                                                                                                                                                                                                                             @ .name) ; succeed) ; succeed.
< 
< '*rule*'("block_alignment",
<          @,
<          @) :- is_list_member("alignment",
<                               @), ((parse_mode :== prefix, is_not_token(@)),((@ :== if, ! ; @ :== while), ! ; @ :== for)), !, '*rule_name*' <<- ref("block_alignment"), @ = @,(@ :== {while;
<                                                                                                                                                                                       for}, !, @ = @ .keyword, @ = @ .body,(@ :== block, !, test_alignment(@,
<                                                                                                                                                                                                                                                            @) ; succeed) ; @ :== if, !, @ = @ .keyword, @ = @ .then_body, (@ :== block, !, test_alignment(@,
<                                                                                                                                                                                                                                                                                                                                                           @) ; succeed), @ = @ .else_body,(@ :\== nothing, !, @ = @ .else_keyword,(@ :== block, !, test_alignment(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                   @) ; succeed) ; succeed) ; succeed) ; succeed.
< 
< test_alignment(@,
<                @) :- @ = @ .left_brace, @ = @ .right_brace, (@ .white_spaces :\== " ", !, error_msg("There must be one space between brace and condition",
<                                                                                                     @) ; succeed),(@ .column :\== @ .column, !, error_msg("Brace must be aligned with first character of instruction",
<                                                                                                                                                           @) ; succeed).
< 
< '*rule*'("nested_typedef",
<          @,
<          @) :- is_list_member("type_definition",
<                               @), (parse_mode :== prefix, @ :== type_definition), !, '*rule_name*' <<- ref("nested_typedef"), @ = @ .type,((@ :== protected_type, @ .type :== protected_type), !, error_msg("Only one level of nested parentheses allowed around type definitions",
<                                                                                                                                                                                                             @ .name) ; succeed) ; succeed.
< 
< '*rule*'("contiguous_nested_typedef",
<          @,
<          @) :- is_list_member("type_definition",
<                               @), (parse_mode :== prefix, @ :== type_definition), !, '*rule_name*' <<- ref("contiguous_nested_typedef"), @ = @ .type,(((@ :== protected_type, @ .type :== protected_type), @ .left_parenthesis .next :== "("), !, error_msg("Only one level of contiguous nested parentheses allowed around type definitions",
<                                                                                                                                                                                                                                                             @ .name) ; succeed) ; succeed.
< 
< '*rule*'("assignment_style",
<          @,
<          @) :- is_list_member("operator",
<                               @), (parse_mode :== prefix, is_assignment_operator(@)), !, '*rule_name*' <<- ref("assignment_style"),((@ .white_spaces :\== " ", ! ; @ .next .white_spaces :\== " "), !, error_msg("Assignment operators must be preceded and followed by a single space",
<                                                                                                                                                                                                                  @) ; succeed) ; succeed.
< 
< '*rule*'("adjacent_operators",
<          @,
<          @) :- is_list_member("operator",
<                               @), ((parse_mode :== prefix, is_operator(@)), is_token(@)), !, '*rule_name*' <<- ref("adjacent_operators"),((is_operator(@ .previous), @ .white_spaces :== ""), !, error_msg("Two operators cannot be adjacent",
<                                                                                                                                                                                                            @) ; succeed) ; succeed.
< 
< '*rule*'("uninitialized_variable",
<          @,
<          @) :- is_list_member("semantics",
<                               @), is_expression(@), !, '*rule_name*' <<- ref("uninitialized_variable"), @ = @ .mode, (parse_mode :== prefix, !, @ = @,(@ :== special, !,(@ .operator :== "?", !, verify_init(@ .condition), verify_init(@ .then), verify_init(@ .else) ; @ :== protected_expression, !, verify_init(@ .expression) ; @ :== function_call, !, verify_init(@ .call), verify_init_args(@ .arguments .first_argument) ; @ :== array_reference, !, verify_init(@ .array), verify_init(@ .index) ; verify_init(@ .expression)) ; @ :== infix, !, @ = base_expression(@ .left_expression), ((@ .operator :== "=", @ :== identifier), !, set_feature(uninit_marked,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              true,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              @) ; verify_init(@ .left_expression)), verify_init(@ .right_expression) ; @ :== {prefix;
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               postfix}, !, verify_init(@ .expression) ; succeed) ; succeed),(((parse_mode :== postfix, @ :== infix), @ .operator :== "="), !, @ = base_expression(@ .left_expression),(@ :== identifier, !, @ = declaration_of(@ .id),(@ :== local_declaration, !, set_initialized_variable(@ .id,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             current_instruction .scope) ; succeed) ; succeed) ; succeed) ; succeed.
< 
< verify_init(@) :- @ :== identifier, !,(has_feature(uninit_marked,
<                                                    @), !, succeed ; @ = first_mention_of(@ .id),(@ :== nothing, !, error_msg("Variable may be uninitialized",
<                                                                                                                              @) ; succeed)) ; succeed.
< 
< verify_init_args(@) :- @ :\== nothing, !, verify_init(@ .expression), verify_init_args(@ .next) ; succeed.
< 
< set_initialized_variable(@,
<                          @) :- @ = @,(@ :== then_body, !, @ = @ .instruction, (has_feature(then_init_variables,
<                                                                                            @), !, succeed ; set_feature(then_init_variables,
<                                                                                                                         variables,
<                                                                                                                         @)), set_feature(@,
<                                                                                                                                          init,
<                                                                                                                                          @ .then_init_variables) ; @ :== else_body, !, @ = @ .instruction, (has_feature(else_init_variables,
<                                                                                                                                                                                                                         @), !, succeed ; set_feature(else_init_variables,
<                                                                                                                                                                                                                                                      variables,
<                                                                                                                                                                                                                                                      @)), set_feature(@,
<                                                                                                                                                                                                                                                                       init,
<                                                                                                                                                                                                                                                                       @ .else_init_variables) ; @ :== {for;
<                                                                                                                                                                                                                                                                                                        {while;
<                                                                                                                                                                                                                                                                                                         do_while}}, !, (has_feature(init_variables,
<                                                                                                                                                                                                                                                                                                                                     @), !, succeed ; set_feature(init_variables,
<                                                                                                                                                                                                                                                                                                                                                                  variables,
<                                                                                                                                                                                                                                                                                                                                                                  @)), set_feature(@,
<                                                                                                                                                                                                                                                                                                                                                                                   init,
<                                                                                                                                                                                                                                                                                                                                                                                   @ .init_variables) ; @ :== block, !, @ = @ .block_declarations .local_declarations,(has_feature(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   @), !, set_feature(init,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      true,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      @ .@) ; set_initialized_variable(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       @ .scope)) ; @ :== {nothing;
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           function_body}, !, succeed ; set_initialized_variable(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 @ .scope) ; succeed).
< 
< '*rule*'("propagate_init",
<          @,
<          @) :- is_list_member("semantics",
<                               @), ((@ :== if, is_not_token(@)), parse_mode :== postfix), !, '*rule_name*' <<- ref("propagate_init"), @ = intersect_init_variables(@), set_initialized_variables(@,
<                                                                                                                                                                                                 @ .scope) ; succeed.
< 
< set_initialized_variables(@,
<                           @) :- @ :== [], !, succeed ; set_initialized_variable(@ .first_element,
<                                                                                 @), set_initialized_variables(@ .tail,
<                                                                                                               @).
< 
< intersect_init_variables(@) -> @ | (has_feature(then_init_variables,
<                                                 @), !,(has_feature(else_init_variables,
<                                                                    @), !, @ = intersection(features_list(@ .then_init_variables),
<                                                                                            features_list(@ .else_init_variables)) ; @ = features_list(@ .then_init_variables)) ; has_feature(else_init_variables,
<                                                                                                                                                                                              @), !, @ = features_list(@ .else_init_variables) ; @ = []), cond(@ :== @,
<                                                                                                                                                                                                                                                               @ = unknown).
< 
< intersection(@,
<              @) -> @ | (@ :== [], !, @ = [] ; @ = @ .first_element, @ = intersection(@ .tail,
<                                                                                      @),(member(@,
<                                                                                                 @), !, @ = newlist(@,
<                                                                                                                    @) ; @ = @)), cond(@ :== @,
<                                                                                                                                       @ = unknown).
< 
< base_expression(@) -> @ | (@ :== protected_expression, !, @ = base_expression(@ .expression) ; @ = @), cond(@ :== @,
<                                                                                                             @ = unknown).
< 
< is_expression(@) -> @ | (has_feature(mode,
<                                      @), !, @ = true ; @ = false), cond(@ :== @,
<                                                                         @ = unknown).
< 
< first_mention_of(@) -> @ | (current_block :== nothing, !, @ = external ; @ = search_mention_of(@,
<                                                                                                current_block)), cond(@ :== @,
<                                                                                                                      @ = unknown).
< 
< search_mention_of(@,
<                   @) -> @ | (@ = @,(@ :== block, !, @ = @ .block_declarations .local_declarations,(has_feature(@,
<                                                                                                                @), !,((@ .@ .initialization :\== nothing, ! ; has_feature(init,
<                                                                                                                                                                           @ .@)), !, @ = init ; @ = nothing) ; @ = search_mention_of(@,
<                                                                                                                                                                                                                                      @ .scope)) ; @ :== then_body, !, @ = @ .instruction,((has_feature(then_init_variables,
<                                                                                                                                                                                                                                                                                                        @), has_feature(@,
<                                                                                                                                                                                                                                                                                                                        @ .then_init_variables)), !, @ = init ; @ = search_mention_of(@,
<                                                                                                                                                                                                                                                                                                                                                                                      @ .scope)) ; @ :== else_body, !, @ = @ .instruction,((has_feature(else_init_variables,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                        @), has_feature(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                        @ .else_init_variables)), !, @ = init ; @ = search_mention_of(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      @ .scope)) ; @ :== {for;
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          {while;
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           do_while}}, !,((has_feature(init_variables,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       @), has_feature(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       @ .init_variables)), !, @ = init ; @ = search_mention_of(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                @ .scope)) ; @ :== {nothing;
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    function_body}, !, @ = external ; search_mention_of(@,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        @ .scope) ; succeed)), cond(@ :== @,
<                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    @ = unknown).
< 
< declaration_of(@) -> @ | (current_block :== nothing, !, @ = nothing ; @ = search_declaration(current_block .block_declarations,
<                                                                                              @)), cond(@ :== @,@ = unknown).
< 
< search_declaration(@,
<                    @) -> @ | ((@ :== block_declarations, !, @ = @ .local_declarations ; @ = nothing),(@ :== nothing, !, @ = nothing ; has_feature(@,
<                                                                                                                                                   @), !, @ = @ .@ ; @ = search_declaration(@ .parent_declarations,
<                                                                                                                                                                                            @))), cond(@ :== @,
<                                                                                                                                                                                                       @ = unknown).
---
> '*rule*'(_A: "variable_length",
>          _B,
>          _C) :- is_list_member("declaration",
>                                _C), (parse_mode :== prefix, _B :== local_declaration), !, '*rule_name*' <<- ref(_A), _D = _B .scope, _E = _D .left_brace, _F = _D .right_brace,(_E .file :\== _F .file, !, error_msg("Braces around a block must be in the same file",
>                                                                                                                                                                                                                      _F) ; strlen(_B .name .id) =< sqrt(_F .line - _E .line), !, error_msg("Variable name is too short",
>                                                                                                                                                                                                                                                                                            _B .name) ; succeed) ; succeed.
> 
> '*rule*'(_A: "extern_in_c_file",
>          _B,
>          _C) :- is_list_member("declaration",
>                                _C), (parse_mode :== prefix, _B :== external_declaration), !, '*rule_name*' <<- ref(_A),((_B .type .store_class :== extern, file_extension(_B .name .file) :== "c"), !, error_msg("No declaration in a .c file accessed out of the .c file",
>                                                                                                                                                                                                                  _B .name) ; succeed) ; succeed.
> 
> '*rule*'(_A: "block_alignment",
>          _B,
>          _C) :- is_list_member("alignment",
>                                _C), ((parse_mode :== prefix, is_not_token(_B)),((_B :== if, ! ; _B :== while), ! ; _B :== for)), !, '*rule_name*' <<- ref(_A), _D = _B,(_D :== {while;
>                                                                                                                                                                                 for}, !, _E = _B .keyword, _F = _B .body,(_F :== block, !, test_alignment(_E,
>                                                                                                                                                                                                                                                           _F) ; succeed) ; _D :== if, !, _G = _B .keyword, _H = _B .then_body, (_H :== block, !, test_alignment(_G,
>                                                                                                                                                                                                                                                                                                                                                                 _H) ; succeed), _I = _B .else_body,(_I :\== nothing, !, _J = _B .else_keyword,(_I :== block, !, test_alignment(_J,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                _I) ; succeed) ; succeed) ; succeed) ; succeed.
> 
> test_alignment(_A,
>                _B) :- _C = _B .left_brace, _D = _B .right_brace, (_C .white_spaces :\== " ", !, error_msg("There must be one space between brace and condition",
>                                                                                                           _C) ; succeed),(_D .column :\== _A .column, !, error_msg("Brace must be aligned with first character of instruction",
>                                                                                                                                                                    _D) ; succeed).
> 
> '*rule*'(_A: "nested_typedef",
>          _B,
>          _C) :- is_list_member("type_definition",
>                                _C), (parse_mode :== prefix, _B :== type_definition), !, '*rule_name*' <<- ref(_A), _D = _B .type,((_D :== protected_type, _D .type :== protected_type), !, error_msg("Only one level of nested parentheses allowed around type definitions",
>                                                                                                                                                                                                      _B .name) ; succeed) ; succeed.
> 
> '*rule*'(_A: "contiguous_nested_typedef",
>          _B,
>          _C) :- is_list_member("type_definition",
>                                _C), (parse_mode :== prefix, _B :== type_definition), !, '*rule_name*' <<- ref(_A), _D = _B .type,(((_D :== protected_type, _D .type :== protected_type), _D .left_parenthesis .next :== "("), !, error_msg("Only one level of contiguous nested parentheses allowed around type definitions",
>                                                                                                                                                                                                                                            _B .name) ; succeed) ; succeed.
> 
> '*rule*'(_A: "assignment_style",
>          _B,
>          _C) :- is_list_member("operator",
>                                _C), (parse_mode :== prefix, is_assignment_operator(_B)), !, '*rule_name*' <<- ref(_A),((_B .white_spaces :\== " ", ! ; _B .next .white_spaces :\== " "), !, error_msg("Assignment operators must be preceded and followed by a single space",
>                                                                                                                                                                                                       _B) ; succeed) ; succeed.
> 
> '*rule*'(_A: "adjacent_operators",
>          _B,
>          _C) :- is_list_member("operator",
>                                _C), ((parse_mode :== prefix, is_operator(_B)), is_token(_B)), !, '*rule_name*' <<- ref(_A),((is_operator(_B .previous), _B .white_spaces :== ""), !, error_msg("Two operators cannot be adjacent",
>                                                                                                                                                                                                _B) ; succeed) ; succeed.
> 
> '*rule*'(_A: "uninitialized_variable",
>          _B,
>          _C) :- is_list_member("semantics",
>                                _C), is_expression(_B), !, '*rule_name*' <<- ref(_A), _D = _B .mode, (parse_mode :== prefix, !, _E = _D,(_E :== special, !,(_B .operator :== "?", !, verify_init(_B .condition), verify_init(_B .then), verify_init(_B .else) ; _B :== protected_expression, !, verify_init(_B .expression) ; _B :== function_call, !, verify_init(_B .call), verify_init_args(_B .arguments .first_argument) ; _B :== array_reference, !, verify_init(_B .array), verify_init(_B .index) ; verify_init(_B .expression)) ; _E :== infix, !, _F = base_expression(_B .left_expression), ((_B .operator :== "=", _F :== identifier), !, set_feature(uninit_marked,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  true,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  _F) ; verify_init(_B .left_expression)), verify_init(_B .right_expression) ; _E :== {prefix;
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       postfix}, !, verify_init(_B .expression) ; succeed) ; succeed),(((parse_mode :== postfix, _D :== infix), _B .operator :== "="), !, _F = base_expression(_B .left_expression),(_F :== identifier, !, _G = declaration_of(_F .id),(_G :== local_declaration, !, set_initialized_variable(_F .id,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              current_instruction .scope) ; succeed) ; succeed) ; succeed) ; succeed.
> 
> verify_init(_A) :- _A :== identifier, !,(has_feature(uninit_marked,
>                                                      _A), !, succeed ; _B = first_mention_of(_A .id),(_B :== nothing, !, error_msg("Variable may be uninitialized",
>                                                                                                                                    _A) ; succeed)) ; succeed.
> 
> verify_init_args(_A) :- _A :\== nothing, !, verify_init(_A .expression), verify_init_args(_A .next) ; succeed.
> 
> set_initialized_variable(_A,
>                          _B) :- _C = _B,(_C :== then_body, !, _D = _B .instruction, (has_feature(then_init_variables,
>                                                                                                  _D), !, succeed ; set_feature(then_init_variables,
>                                                                                                                                variables,
>                                                                                                                                _D)), set_feature(_A,
>                                                                                                                                                  init,
>                                                                                                                                                  _D .then_init_variables) ; _C :== else_body, !, _D = _B .instruction, (has_feature(else_init_variables,
>                                                                                                                                                                                                                                     _D), !, succeed ; set_feature(else_init_variables,
>                                                                                                                                                                                                                                                                   variables,
>                                                                                                                                                                                                                                                                   _D)), set_feature(_A,
>                                                                                                                                                                                                                                                                                     init,
>                                                                                                                                                                                                                                                                                     _D .else_init_variables) ; _C :== {for;
>                                                                                                                                                                                                                                                                                                                        {while;
>                                                                                                                                                                                                                                                                                                                         do_while}}, !, (has_feature(init_variables,
>                                                                                                                                                                                                                                                                                                                                                     _B), !, succeed ; set_feature(init_variables,
>                                                                                                                                                                                                                                                                                                                                                                                   variables,
>                                                                                                                                                                                                                                                                                                                                                                                   _B)), set_feature(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                     init,
>                                                                                                                                                                                                                                                                                                                                                                                                     _B .init_variables) ; _C :== block, !, _E = _B .block_declarations .local_declarations,(has_feature(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         _E), !, set_feature(init,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             true,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             _E ._A) ; set_initialized_variable(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                _B .scope)) ; _C :== {nothing;
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      function_body}, !, succeed ; set_initialized_variable(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            _B .scope) ; succeed).
> 
> '*rule*'(_A: "propagate_init",
>          _B,
>          _C) :- is_list_member("semantics",
>                                _C), ((_B :== if, is_not_token(_B)), parse_mode :== postfix), !, '*rule_name*' <<- ref(_A), _D = intersect_init_variables(_B), set_initialized_variables(_D,
>                                                                                                                                                                                         _B .scope) ; succeed.
> 
> set_initialized_variables(_A,
>                           _B) :- _A :== [], !, succeed ; set_initialized_variable(_A .first_element,
>                                                                                   _B), set_initialized_variables(_A .tail,
>                                                                                                                  _B).
> 
> intersect_init_variables(_A) -> _B | (has_feature(then_init_variables,
>                                                   _A), !,(has_feature(else_init_variables,
>                                                                       _A), !, _B = intersection(features_list(_A .then_init_variables),
>                                                                                                 features_list(_A .else_init_variables)) ; _B = features_list(_A .then_init_variables)) ; has_feature(else_init_variables,
>                                                                                                                                                                                                      _A), !, _B = features_list(_A .else_init_variables) ; _B = []), cond(_B :== @,
>                                                                                                                                                                                                                                                                           _B = unknown).
> 
> intersection(_A,
>              _B) -> _C | (_A :== [], !, _C = [] ; _D = _A .first_element, _E = intersection(_A .tail,
>                                                                                             _B),(member(_D,
>                                                                                                         _B), !, _C = newlist(_D,
>                                                                                                                              _E) ; _C = _E)), cond(_C :== @,
>                                                                                                                                                    _C = unknown).
> 
> base_expression(_A) -> _B | (_A :== protected_expression, !, _B = base_expression(_A .expression) ; _B = _A), cond(_B :== @,
>                                                                                                                    _B = unknown).
> 
> is_expression(_A) -> _B | (has_feature(mode,
>                                        _A), !, _B = true ; _B = false), cond(_B :== @,
>                                                                              _B = unknown).
> 
> first_mention_of(_A) -> _B | (current_block :== nothing, !, _B = external ; _B = search_mention_of(_A,
>                                                                                                    current_block)), cond(_B :== @,
>                                                                                                                          _B = unknown).
> 
> search_mention_of(_A,
>                   _B) -> _C | (_D = _B,(_D :== block, !, _E = _B .block_declarations .local_declarations,(has_feature(_A,
>                                                                                                                       _E), !,((_E ._A .initialization :\== nothing, ! ; has_feature(init,
>                                                                                                                                                                                     _E ._A)), !, _C = init ; _C = nothing) ; _C = search_mention_of(_A,
>                                                                                                                                                                                                                                                     _B .scope)) ; _D :== then_body, !, _F = _B .instruction,((has_feature(then_init_variables,
>                                                                                                                                                                                                                                                                                                                           _F), has_feature(_A,
>                                                                                                                                                                                                                                                                                                                                            _F .then_init_variables)), !, _C = init ; _C = search_mention_of(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                             _F .scope)) ; _D :== else_body, !, _F = _B .instruction,((has_feature(else_init_variables,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   _F), has_feature(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    _F .else_init_variables)), !, _C = init ; _C = search_mention_of(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     _F .scope)) ; _D :== {for;
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           {while;
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            do_while}}, !,((has_feature(init_variables,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        _B), has_feature(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         _B .init_variables)), !, _C = init ; _C = search_mention_of(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     _B .scope)) ; _D :== {nothing;
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           function_body}, !, _C = external ; search_mention_of(_A,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                _B .scope) ; succeed)), cond(_C :== @,
>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             _C = unknown).
> 
> declaration_of(_A) -> _B | (current_block :== nothing, !, _B = nothing ; _B = search_declaration(current_block .block_declarations,
>                                                                                                  _A)), cond(_B :== @,_B = unknown).
> 
> search_declaration(_A,
>                    _B) -> _C | ((_A :== block_declarations, !, _D = _A .local_declarations ; _D = nothing),(_D :== nothing, !, _C = nothing ; has_feature(_B,
>                                                                                                                                                           _D), !, _C = _D ._B ; _C = search_declaration(_A .parent_declarations,
>                                                                                                                                                                                                         _B))), cond(_C :== @,
>                                                                                                                                                                                                                     _C = unknown).
