Discussion:
Refined types [almost OT]
bearophile via Digitalmars-d
2014-10-12 16:21:49 UTC
Permalink
A series of small OCaML projects that implement bare-bones type
systems. This implements a basic Refined Typing and explains the
nice ideas:
https://github.com/tomprimozic/type-systems/tree/master/refined_types


This is one example (the unrefined underlying types are managed
with a standard global inferencer):

function get_2dimensional(n : int if n >= 0, m : int if m >= 0,
i : int if 0 <= i and i < m, j : int if
0 <= j and j < n,
arr : array[int] if length(arr) == m *
n) {
return get(arr, i * n + j)
}


In D syntax may become:

double get2dimensional(int n: if n >= 0,
int m: if m >= 0,
int i: if 0 <= i && i < m,
int j: if 0 <= j && j < n,
double[] arr: if arr.length == m * n) {
return arr[i * n + j];
}


In theory pre-conditions could be used:


double get2D(in size_t row, in size_t col,
in size_t nRows, in size_t nCols,
in double[] mat)
pure nothrow @safe @nogc in {
assert(row < nRows);
assert(col < nCols);
assert(arr.length == nRows * nCols);
} body {
return mat[row * nCols + col];
}


In practice I don't know if it's a good idea to mix the
potentially very hard to verify pre-conditions with the limited
but statically enforced type refinements. So perhaps using the ":
if" syntax on the right of types is still the best option to use
refinement typing in a D-like language. In this case the
contracts keep being enforced at run-time, and can contain more
complex invariants and tests that the refinement typing can't
handle.
The get_2dimensional function is particularly interesting; it
uses non-linear integer arithmetic, which is incomplete and
undecidable. Although Z3 can prove simple non-linear statements
about integers, such as x^2 = 0, it cannot prove that the array
is accessed within bound in the function get_2dimensional.
Instead, it has to convert the formula to real arithmetic and
use the NLSat solver [5]. Even though non-linear real arithmetic
is complete and decidable, this approach only works for certain
kinds of problems; for example, it cannot disprove equalities
that have real solutions but no integer ones, such as x^3 + y^3
== z^3 where x, y and z are positive.<
Bye,
bearophile
Meta via Digitalmars-d
2014-10-12 19:21:25 UTC
Permalink
On Sunday, 12 October 2014 at 16:21:50 UTC, bearophile wrote:
What happens if one of these conditions fails? Is an exception
thrown? Note that you can also sort of do this using template
constraints, but that of course only works at compile time:

double get2dimensional(int n, int m, int i, int j, double[] arr)()
if (n >= 0
&& m >= 0
&& 0 <= i
&& i < m
&& 0 <= j
&& j < n
&& arr.length == m * n)
{
return arr[i * n + j];
}
bearophile via Digitalmars-d
2014-10-12 19:36:34 UTC
Permalink
Post by Meta via Digitalmars-d
What happens if one of these conditions fails? Is an exception
thrown?
If you are using refined types, and D is somewhat assuming they
are refinements of those types, and one of those condition fails,
then you surely have a compile-time type error, because those
conditions are an intrinsic part of those type definition.

Bye,
bearophile
Meta via Digitalmars-d
2014-10-12 19:41:34 UTC
Permalink
Post by bearophile via Digitalmars-d
Post by Meta via Digitalmars-d
What happens if one of these conditions fails? Is an exception
thrown?
If you are using refined types, and D is somewhat assuming they
are refinements of those types, and one of those condition
fails, then you surely have a compile-time type error, because
those conditions are an intrinsic part of those type definition.
Bye,
bearophile
It's not possible to issue a compile-time error for runtime
arguments, though, and it can already be done in D using template
constraints for compile-time arguments.
Timon Gehr via Digitalmars-d
2014-10-12 20:58:57 UTC
Permalink
What happens if one of these conditions fails? Is an exception thrown?
If you are using refined types, and D is somewhat assuming they are
refinements of those types, and one of those condition fails, then you
surely have a compile-time type error, because those conditions are an
intrinsic part of those type definition.
Bye,
bearophile
It's not possible to issue a compile-time error for runtime arguments,
though,
Yes it is. Why wouldn't it be? Values needn't be completely determined
in order to be reasoned about.
and it can already be done in D using template constraints for
compile-time arguments.
Meta via Digitalmars-d
2014-10-12 23:48:54 UTC
Permalink
Post by Timon Gehr via Digitalmars-d
Yes it is. Why wouldn't it be? Values needn't be completely
determined in order to be reasoned about.
They do if you want to check, for example, n < 3. D doesn't
currently support the type of analysis necessary to implement
something like that.
Timon Gehr via Digitalmars-d
2014-10-13 00:01:02 UTC
Permalink
Post by Timon Gehr via Digitalmars-d
Yes it is. Why wouldn't it be? Values needn't be completely determined
in order to be reasoned about.
They do if you want to check, for example, n < 3. D doesn't currently
support the type of analysis necessary to implement something like that.
(bearophile isn't discussing current language features.)
Meta via Digitalmars-d
2014-10-13 03:48:42 UTC
Permalink
Post by Timon Gehr via Digitalmars-d
Post by Meta via Digitalmars-d
Post by Timon Gehr via Digitalmars-d
Yes it is. Why wouldn't it be? Values needn't be completely
determined
in order to be reasoned about.
They do if you want to check, for example, n < 3. D doesn't
currently
support the type of analysis necessary to implement something
like that.
(bearophile isn't discussing current language features.)
Ridiculous, I'm positive that D fully supports refined types in
the language. Please check your facts.
thedeemon via Digitalmars-d
2014-10-13 08:20:13 UTC
Permalink
Post by Meta via Digitalmars-d
Post by Timon Gehr via Digitalmars-d
Post by Meta via Digitalmars-d
Post by Timon Gehr via Digitalmars-d
Yes it is. Why wouldn't it be? Values needn't be completely
determined
in order to be reasoned about.
They do if you want to check, for example, n < 3. D doesn't
currently
support the type of analysis necessary to implement something like that.
(bearophile isn't discussing current language features.)
Ridiculous, I'm positive that D fully supports refined types in
the language. Please check your facts.
Meta, go home, you're drunk.

This technique is for statically checking certain conditions for
the runtime values. This is what dependently typed languages do
using some proofs (ATS is worth mentioning here, it solves linear
integer conditions automatically using Presburger arithmetic and
lets using more involved proofs to solve nonlinear ones) and
languages with liquid/refined types do using an external SAT
solver. Other than simple value range propagation D doesn't do
anything like this. Arithmetic and conditions in the compile-time
part of the language is not it.
Meta via Digitalmars-d
2014-10-13 13:19:42 UTC
Permalink
Post by thedeemon via Digitalmars-d
Post by Meta via Digitalmars-d
Ridiculous, I'm positive that D fully supports refined types
in the language. Please check your facts.
Meta, go home, you're drunk.
That was a joke.

Continue reading on narkive:
Loading...