I'd love to see that if you don't mind
Excuse me if I make a mistake. I'm not going to write a working program, and I'm not at my usual setup right now.
So, here's an enumeration type in Ada:
Code:
type Traffic_Light is (Red, Yellow, Green);
Types in Ada have attributes. As examples,
Traffic_Light'Pos
returns the zero-indexed position of a value of the type, whereas
Traffic_Light'Val
does the opposite. There are a lot of very convenient attributes like First, Last, Image, and Value, but I won't get into them any.
Here's an array type definition using the earlier type:
Code:
type Expected_Acceleration is array (Traffic_Light) of Integer;
We can define a value of the type like so:
Code:
Laws : Expected_Acceleration := (Green => 1, Yellow => -1, Red => 0);
I could also have written these by position, but I like to use names in all cases, and notice they needn't be in order that way.
So, that's the basic stuff, and it's not really worth it to use Ada 2012 solely to associate a predicate with the type to enforce uniqueness. I don't use Ada 2012, preferring 1995 instead, but the way I'd do it, for constant data and if both were fairly small enumeration types, would be to define both directions as functions and use postconditions instead. The postconditions would just reference each other to ensure uniqueness.
Now, for anything more complex, it would be best to define a generic data type instead. I'll whip up a basic example of that, and examples for the functions I mentioned, in a bit. In fact, one thing the newer Ada standards introduced were so-called container types, fancy things. It'd probably be pretty easy to define a proper group as two maps, with a predicate ensuring the invertible relationship. I'll look into that. Still, if I had to use a group in one of my programs, I'd just use the basic arrays and enforce uniqueness somewhere else.