A late contribution to the discussion:
Since optimized (compiled) arithmetic support was added, user defined arithmetic functions are implemented using library(arithmetic)
. But, as noted above, non-numeric arguments and return values are not supported. Any syntax issues can be dealt with using term/goal expansion, but errors will be generated for non-numerics at evaluation time .
So a couple of years ago I experimented with an extended clone of arithmetic
which did support user defined types - see arithmetic_types
.
Also included are a small set of example types, one being type_stringy
, so:
?- use_module(library(type_stringy)).
true.
?- X is "pi".
X = "pi".
?- "a" < "b".
true.
% `\\` is the concat operator
?- X is "foo" \\ "bar".
X = "foobar".
% slicing and indexing using `op(100, yf, [])`
?- S is "abc"[0].
S = a.
?- S is "abc"[-1].
S = c.
?- S is "abc"[1:E].
S = "bc",
E = 3.
?- P is find("cd","abcdef").
P = 2.
But my main motivation was to support N-dimensional numeric arrays for representing a linear system of equations that could be solved using Cramer’s Rule, e.g, solving:
x + y + z + w = 13
2x + 3y − w = −1
−3x + 4y + z + 2w = 10
x + 2y − z + w = 1
with
?- set_prolog_flag(prefer_rationals,true), use_module(library(type_ndarray)).
true.
?- _A is ndarray([[1,1,1,1],[2,3,0,-1],[-3,4,1,2],[1,2,-1,1]]),
_B is ndarray([[13],[-1],[10],[1]]),
Vs is ndarray([[X],[Y],[Z],[W]]),
Vs is dot(inverse(_A),_B).
Vs = #(#(2), #(0), #(6), #(5)),
X = 2,
Y = 0,
Z = 6,
W = 5.
I don’t think it’s inappropriate to support these extended types in arithmetic evaluation because often the arguments, e.g., an index into a string, or the result, e.g., the position in a string of a substring, are numeric, so it’s useful to be able to mix numeric and non-numeric values in a single expression using an extended set of functions.
I do think this is all too immature to be considered PIP worthy and I’m unaware of any similar capabilities in other Prolog’s. But the ability to port something like this would be simplified if the underlying foundation was somewhat “standardized” via the PIP process (perhaps some already are), e.g., things like
- term and goal expansion
- bracket style operators (to support index and slice syntax)
arithmetic_function
directive equivalent
predicate_property
equivalent for finding loaded (polymorphic) arithmetic functions
But IMO I think Peter’s correct in stating that much of this can be accommodated by “a small matter of programming, and not a reason for major changes one way or the other” (ignoring performance issues, of course?).