FeatureVectors (Review of programming a data type)

Summary

Create a class (FeatureVector) that implements a feature vector.

Ask an AI to generate an appropriate testing program, and examine that program to make sure that it's testing for every condition listed below. Revise that program (either yourself or by prompting the AI) until you are satisfied that it tests everything. Submit that testing program as MyFVTest.

MyTestFV should run on its own and report either PASS or FAIL for each test it runs (identifying the test in the output). I don't want you to provide a JUnit test class.

Background

Feature vectors are sometimes used to represent information about language (among other things). Each vector may have a value for each name in a feature set. For example, if the possible features are HIGH, FRONT and ROUND, then a feature vector might represent a high-front vowel

[
      HIGH: true
     FRONT: true
]
or a low-round vowel
[
      HIGH: false
     ROUND: true
]
In the first example, the value for HIGH is true (the vowel is high), while in the second example it's false (the vowel is low). The first example has no value for ROUND, and the second has no value for FRONT.

A vector can have values for all, many, few, one or even none of the features. But each feature can only have one value. For example, a vector can't represent a vowel; that's both high and low

[
      HIGH: true
      HIGH: false
]
NOT ALLOWED!!!!
Also the vector is not allowed to have values for features that aren't in its feature set:
[
      HIGH: true
    NOSUCH: false
]
NOT ALLOWED!!!!

The values can be any Object. I've used boolean values above, but I could have used Strings or Integers, or even some user-defined type. Consider this example on the feature set NUMBER, PERSON, GENDER, CASE:

[
    NUMBER: singular
    PERSON: 3
]
The NUMBER is a String and the PERSON is an Integer. Here's another example:
[
      CASE: dative
]
Another String.

Feature values can't be set to null, however.

[
      HIGH: null
]
NOT ALLOWED (unless it's the String "null")

Feature vectors can be "added together". The "sum" of two feature vectors is just the union of all the features defined in those two vectors. For example, the sum of

[
    NUMBER: singular
    PERSON: 3
]
and
[
      CASE: dative
]
is:
[
    NUMBER: singular
    PERSON: 3
      CASE: dative
]
It combines the NUMBER and PERSON values from one of them with the CASE value from the other.

It's possible that the two vectors we're adding together both have a value for one feature. In that case we need to take care. If the values are the same, we're fine. For example, if we add

[
    NUMBER: singular
    PERSON: 3
      CASE: dative
]
with the vector
[
    GENDER: neuter
      CASE: dative
]
then we get
[
    NUMBER: singular
    PERSON: 3
    GENDER: neuter
      CASE: dative
]
In both cases the CASE is dative, so there's not problem.

But if the values are different, then the two vectors cannot be added together. For example:

[
    GENDER: neuter
      CASE: dative
]
and
[
    NUMBER: 2
      CASE: nominative
]
have no sum. We have inconsistent information about what the CASE value is.

When we add together two vectors with inconsistent information, we get what we'll call a failure vector. It is a special vector that represents inconsistent information. I'll write it out like this:

[
--FAILURE--
]
Some people call this vector "top", and others call it "bottom". I'm avoiding the issue by just saying it's a failure vector.

Details

FeatureVector has the following responsibilities:

Make sure you throw appropriate exceptions for each error condition. Some exception classes you might like to use:

Each thrown exception should have an appropriate message.

Grading Outline