Friday, October 5, 2018

Ada 2012 Static Predicates


1.     Subtypes

Every Ada type is associated with a subtype. A subtype is a subset of the base type, commonly with some restriction in the set of values valid for the subtype. For instance, Ada provides a pre-defined type named Integer. Integer is a signed type representing all the values in the range of -2**31..2**31 – 1. Ada also provides two pre-defined subtypes of Integer: Natural, which is an integer with a minimum value of 0, and Positive which is an integer with a minimum value of 1. Every instance of Natural or Positive is also an instance of Integer. This capability to define subtypes has been a part of Ada since the first Ada language standard in 1983.
While this subtype capability has been very useful, it had some restrictions. Subtype ranges were always restricted to contiguous ranges. For instance, the syntax for defining the Natural subtype mentioned above is:
subtype Natural is Integer range 0..Integer’Last;
 Integer’Last evaluates to the highest valid value defined for the type Integer.

2.     Static Predicates

Ada 2012 added new capabilities to the definition of subtypes. One of those capabilities is the definition of static predicates. Static predicates allow the definition of statically defined non-contiguous sets of values.
For instance, a subtype of the pre-defined type Character can be defined to contain only the letters in the ASCII subset of Character:
subtype Letters is Character with Static_Predicate => ‘A’..’Z’ | ‘a’..’z’;
Notice that the subtype Letters contains two contiguous ranges. One range includes the upper case letters and the other contains the lower case letters. Similarly one can define a subtype with no contiguous ranges of values such as:
subtype Vowels is Character with Static_Predicate => ‘A’ | ‘E’ | ‘I’ | ‘O’ | ‘U’ | ‘a’ | ‘e’ | ‘i’ | ‘o’ | ’u’;

2.1. Example

Following are two programs used to calculate the number of vowels and consonants in a string read from standard input. The C code is taken from https://www.sanfoundry.com/c-program-count-number-vowels-consonants-sentence/
Both programs achieve the same goal with some problems in the C code dealing with punctuation and tab characters.

2.1.1.     C Code

/*
 * C program to read a sentence and count the total number of vowels
 * and consonants in the sentence.
 */
#include <stdio.h>

void main()
{
    char sentence[80];
    int i, vowels = 0, consonants = 0, special = 0;

    printf("Enter a sentence \n");
    gets(sentence);
    for (i = 0; sentence[i] != '\0'; i++)
    {
        if ((sentence[i] == 'a' || sentence[i] == 'e' || sentence[i] ==
        'i' || sentence[i] == 'o' || sentence[i] == 'u') ||
        (sentence[i] == 'A' || sentence[i] == 'E' || sentence[i] ==
        'I' || sentence[i] == 'O' || sentence[i] == 'U'))
        {
            vowels = vowels + 1;
        }
        else
        {
            consonants = consonants + 1;
        }
        if (sentence[i] =='t' ||sentence[i] =='\0' || sentence[i] ==' ')
        {
            special = special + 1;
        }
    }
    consonants = consonants - special;
    printf("No. of vowels in %s = %d\n", sentence, vowels);
    printf("No. of consonants in %s = %d\n", sentence, consonants);
}

2.1.2.     Ada 2012 Code

-----------------------------------------------------------------------
-- Count the number of vowels and consonants in an input string
-----------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_Io;

procedure Count_Letters is
   subtype Vowels is Character with
     Static_Predicate => Vowels in
       'A' | 'E' | 'I' | 'O' | 'U' | 'a' | 'e' | 'i' | 'o' | 'u';
   subtype Letters is Character with
     Static_Predicate => Letters in 'A'..'Z' | 'a'..'z';
   Msg         : String(1..1024);
   Length      : Natural;
   Cons_Count  : Natural := 0;
   Vowel_Count : Natural := 0;
begin
   Put("Enter phrase: ");
   Get_Line(Msg, Length);
   for Char of Msg(1..Length) loop
      if Char in Vowels then
         Vowel_Count := Vowel_Count + 1;
      elsif Char in Letters then
         Cons_Count := Cons_Count + 1;
      end if;
   end loop;
   Put_Line('"' & Msg(1..Length) & '"' & " contains" & Vowel_Count'Image &
              " vowels and" & Cons_Count'Image & " consonants.");
end Count_Letters;

The subtypes Vowels and Letters are used to define sets of values. The “if” statement tests each character of the input string for membership in one set or the other. All characters not in either set, such as spaces or punctuation, are not counted. Note that the C version of the program counts all characters which are not vowels then subtracts specified non-letter characters. The C code will actually count punctuation as consonants because it does not include those characters in its list of special characters. On the other hand the Ada code contains positive definitions of the characters to be counted and only counts the specified characters. This ability to unambiguously define the set of characters to count eliminates a set of errors hidden in the C code.

No comments:

Post a Comment

Comparison of three algorithms for summing an array of integers

This article shares a comparison of the time taken to sum an array of integers. This article tests three algorithms for summing the array. •...