Open wenkokke opened 1 year ago
To solve this, we should separated logical operations for properties and for "slices"...
-- embedding slices into booleans
SliceToBool :: Slice -> Bool
-- splitting boolean connectives out into boolean and slice variants
And :: Bool -> Bool -> Bool
AndSlice :: Slice -> Slice -> Slice
Implies :: Bool -> Bool -> Bool
ImpliesSlice :: Slice -> Slice -> Slice
Not :: Bool -> Bool
NotSlice :: Slice -> Slice
Or :: Bool -> Bool -> Bool
OrSlice :: Slice -> Slice -> Slice
-- changing the types of comparisons on indexes
EqIndex :: Index -> Index -> Slice
GeIndex :: Index -> Index -> Slice
GtIndex :: Index -> Index -> Slice
LeIndex :: Index -> Index -> Slice
LtIndex :: Index -> Index -> Slice
NeIndex :: Index -> Index -> Slice
For the immediate future, we can interpret Slice as a bool that consists only of comparisons on values of type Index, and interpret Bool as Rat, for the loss function semantics, and instantiate it as Never on the Python side to indicate the fact that these should never be returned as part of a loss function. This lets us separate out their interpretation for TensorFlow, which means we get (1) fast graph-based operations, and (2) sensible semantics for indexes.
In the future, we should interpret Slice as numpy index arrays, i.e., Array[int]
where int is restricted to 0 and 1.
This interpretation requires a little bit of work to push the logical operations on slices down into the call to indices.
Okay, so after further consideration:
My intuition says...
...should translate to something like...
...but if I understand the current translation actually translates this to...
...which has a completely different and arguably unintuitive semantics.