July 07

On Friday, 7 July 2023 at 13:28:23 UTC, Quirin Schroll wrote:

>

The last two or three are debatable; I have not put them in Rewrites intentionally. As presented, the intervals don’t adhere to the last two. It’s not even clear what == on the intervals would be. It looks like the intervals are supposed to represent any value in the bounds, which means that – unless the lower and bound is the same, i.e. the interval is a single number – I == I should actually fail.

This is exactly how I define equality (which differs from how math folks define it); if X and Y are intervals then the comparison between them must hold for all possible values of these intervals which means equality only holds if they converge on a single point on the numerical axis. Seems like the only definition that's useful for implementing VRP.

>

The C++ proposal P0515R0 is also a good read. It was rejected, but introduces relevant notions. Look at least at § 1.4.1 Guidance: What we teach.

That's an interesting read, thanks for the link.

July 07

On Friday, 7 July 2023 at 09:18:38 UTC, Ahmet Sait wrote:

>

Let's define two intervals x and y:
{x ∈ ℝ │ a ≤ x ≤ b}
{y ∈ ℝ │ c ≤ y ≤ d}

And the inequality operators:

x < y = ⎧ 1  if b < c
        ⎨
        ⎩ 0  otherwise

x ≤ y = ⎧ 1  if b ≤ c
        ⎨
        ⎩ 0  otherwise

x > y = ⎧ 1  if a > d
        ⎨
        ⎩ 0  otherwise

x ≥ y = ⎧ 1  if a ≥ d
        ⎨
        ⎩ 0  otherwise

Exercise: Write an opCmp() method that implements the rules above for struct Interval { int lower, upper; }. (Hint: It's not possible.)

Thanks god. If you are doing something non standard, do not use the builtin operators, give you operation an explicit name.

July 07
On Friday, July 7, 2023 10:18:56 AM MDT deadalnix via Digitalmars-d wrote:
> On Friday, 7 July 2023 at 09:18:38 UTC, Ahmet Sait wrote:
> > Let's define two intervals x and y:
> > {x ∈ ℝ │ a ≤ x ≤ b}
> > {y ∈ ℝ │ c ≤ y ≤ d}
> >
> > And the inequality operators:
> > ```
> > x < y = ⎧ 1  if b < c
> >
> > > >         ⎩ 0  otherwise
> >
> > x ≤ y = ⎧ 1  if b ≤ c
> >
> > > >         ⎩ 0  otherwise
> >
> > x > y = ⎧ 1  if a > d
> >
> > > >         ⎩ 0  otherwise
> >
> > x ≥ y = ⎧ 1  if a ≥ d
> >
> > > >         ⎩ 0  otherwise
> >
> > ```
> >
> > Exercise: Write an `opCmp()` method that implements the rules
> > above for `struct Interval { int lower, upper; }`. (Hint: It's
> > not possible.)
>
> Thanks god. If you are doing something non standard, do not use the builtin operators, give you operation an explicit name.

Yeah. The limitations on opCmp are very much on purpose. We already arguably have issues due to how the comparison operations work with NaN (it's a useful feature, but it does potentially cause problems with generic code). The comparison operators are very much intended to work in the standard manner even on user-defined types, and types where that isn't going to work should be using a different set of functions.

Operator overloading in general is provided so that user-defined types can be used like built-in types and work with generic code that uses those operators. Domain-specific language stuff should probably be left to either a domain-specific language or just use properly named functions. Trying to alter the built-in operators to operate in a way that differs like this from the built-in types is arguably an abuse of operator overloading.

So, while obviously, if someone is looking to do this like they might have done in C++, that can be annoying for them, it's really not something that D is looking to support.

- Jonathan M Davis




July 07
On 7/7/23 17:49, Ahmet Sait wrote:
> Seems like the only definition that's useful for implementing VRP.

VRP is a kind of abstract interpretation, and the natural definition for that is the perfect transformer:

`I op I' = { I op I' | x∈I, x'∈I' }`

I.e., I'd say it is more useful to have three-valued logic operating on `{false}`, `{true}` and `{false,true}`.

Alternatively,

`I <=> I' = { I <=> I' | x∈I, x'∈I' }`

producing a non-empty subset of `{-1,0,1}`.

In any case, implementing abstract interpretation as operations on independent abstract elements in the first place is not particularly natural and only works in very special cases such as the interval domain.
July 08
On Friday, 7 July 2023 at 17:15:45 UTC, Timon Gehr wrote:
> On 7/7/23 17:49, Ahmet Sait wrote:
>> Seems like the only definition that's useful for implementing VRP.
>
> VRP is a kind of abstract interpretation, and the natural definition for that is the perfect transformer:
>
> `I op I' = { I op I' | x∈I, x'∈I' }`
>
> I.e., I'd say it is more useful to have three-valued logic operating on `{false}`, `{true}` and `{false,true}`.
>
> Alternatively,
>
> `I <=> I' = { I <=> I' | x∈I, x'∈I' }`
>
> producing a non-empty subset of `{-1,0,1}`.
>
> In any case, implementing abstract interpretation as operations on independent abstract elements in the first place is not particularly natural and only works in very special cases such as the interval domain.

You're all aware that opCmp can return a float, with the values 0,1,-1 and NaN?
This can be used for intervals very good (returning NaN if the intervals overlap, 0 if they are equal and 1 or -1 if they are disjunct).
Unfortunately float is 32 bit, so pretty much the first thing I did after I found D was to implement a 2-bit type with exactly those 4 values.
July 08
On Saturday, 8 July 2023 at 08:32:00 UTC, Dom DiSc wrote:
> You're all aware that opCmp can return a float, with the values 0,1,-1 and NaN?
> This can be used for intervals very good (returning NaN if the intervals overlap, 0 if they are equal and 1 or -1 if they are disjunct).

You're more than welcome to prove us wrong ;)
July 08
On 7/8/23 10:32, Dom DiSc wrote:
>>
>> In any case, implementing abstract interpretation as operations on independent abstract elements in the first place is not particularly natural and only works in very special cases such as the interval domain.
> 
> You're all aware that opCmp can return a float, with the values 0,1,-1 and NaN?
> This can be used for intervals very good (returning NaN if the intervals overlap, 0 if they are equal and 1 or -1 if they are disjunct).
> Unfortunately float is 32 bit, so pretty much the first thing I did after I found D was to implement a 2-bit type with exactly those 4 values.

I am very aware of this. OTOH, you may not be aware that your solution does not satisfy the OP's constraints.

It cannot do so because D's operator overloading while not enforcing
`a <= b || b < a` still enforces `a <= b <==> a < b || b <= a`, but
while `[x,y] <= [y,z]` holds, neither `[x,y] < [y,z]` nor
`[y,z] <= [x,y]` hold for x<y<z`.

This means the OP is indeed right that it is impossible.
July 08
On 7/8/23 19:22, Timon Gehr wrote:
> `a <= b <==> a < b || b <= a`

Typo. This is of course only an implication:

`a <= b ==> a < b || b <= a`.

In any case, the argument stands.
July 09

On Friday, 7 July 2023 at 09:18:38 UTC, Ahmet Sait wrote:

>

I dislike the current scheme because its not very meta programmable

like, id like to write Nullable!T opcmp in 3 lines of code

opCmp(typeof(this) a){
  if(a.isnull != isnull){
    return isnull.opCmp(a.isnull);}
  return value.opCmp(a.value);
}

That is very very much NOT how it works; maybe it should act like opBinary and
a < b is rewritten as a.opCmp!"<"(b) with some list of prefered overloads

1 2
Next ›   Last »