with ada.text_io; use ada.text_io; 
with ada.integer_text_io; use ada.integer_text_io; 
 
-- Print list of unique words and their frequencies
-- A word is a line of data
procedure wf is
    MaxWordLen: Constant Natural := 80;
    MaxWordCount: Constant Natural := 1000;
 
    type word is record
        letters: String(1..MaxWordLen);
        len: Natural := 0;
        freq: Natural := 0;
    end record;
 
    type WordArray is array(Natural range <>) of Word;
 
    type WordList is record
        theWords: WordArray(1..MaxWordCount);
        size: Natural := 0;
    end record;

    -- Define equality for words
    function "="(left, right: word) return boolean is
    begin
        return left.letters(1 .. left.len) = right.letters(1 .. right.len);
    end "=";

    -- Process a word by counting it or adding it to the array
    procedure processWord(w: in word; l: in out wordlist) is
        found: boolean := false;
        location: Natural;
    begin
        -- Determine if w is in the array, and if so, where
        for i in 1 .. l.size loop
            if l.theWords(i) = w then
                found := true;    -- Remember that we found the word
                location := i;    -- Remember where the word was
            end if;
        end loop;
            
        if found then 
            -- The word was already in the array, so count it
            l.thewords(location).freq := l.thewords(location).freq + 1;
        else
            -- The word was not in the array, so add it
            l.size := l.size + 1;           -- Increase number of unique words
            l.thewords(l.size) := w;
            l.thewords(l.size).freq := 1;
        end if;
    end processWord;

 
    -- Input and count all of the words
    procedure getwords(l: out wordlist) is
        w: Word;
    begin
        while not end_of_file loop
            get_line(w.letters, w.len);
            processWord(w, l);
        end loop;
    end getwords;
 
    -- Output all of the words and their frequencies
    procedure putwordsandfreq(l: wordlist) is
        w: Word;
    begin
        for i in 1 .. l.size loop
            w := l.thewords(i);
            put(w.letters(1 .. w.len));
            put(w.freq);
            new_line;
        end loop;
    end putwordsandfreq;

    l: wordlist;

begin
    getwords(l);
    putwordsandfreq(l);
end wf;