But then the journey was not over, we had also to
handle these cases, which are not handled through
token aliasing detecting, but through context flags:
:- X = (-) - -, write(X), nl.
:- X = - - -, write(X), nl.
:- X = - (a,b,c), write(X), nl.
:- X = -(a,b,c), write(X), nl.
:- X = - 1, write(X), nl.
:- X = -1, write(X), nl.
(-)- -
- - -
- (a, b, c)
-(a, b, c)
- 1
-1
The relevant context flags now also implemented
by Dogelog Runtime directly in Prolog, formerly found
in Jekejeke Prolog implemented in Java:
- SPEZ_OPER: 1 for (-)- - versus - - -
- SPEZ_FUNC: 2 for - (a, b, c) versus -(a, b, c)
- SPEZ_MINS: 4 for - 1 versus -1
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 10:57:28 UTC+2:
Using the compressed unicode now for:
- detecting whether an atom needs quote
- detecting whether tokens alias during writing
We do it slightly different than in Jekejeke Prolog, without a word
break 2 dimensional matrice. The word break 2 dimensional matrice
seems to be not anymore needed, only a few cases are relevant,
which can be directly coded as Prolog predicates:
is_name is_name
is_symbol is_symbol
\' \'
After a journey into enhancing write_term/1, the compact
writing of operators now does not give anymore:
:- X = 1 rem 2, write(X), nl.
:- X = (1+2) rem 3, write(X), nl.
:- X = ** rem **, write(X), nl.
1rem2
(1+2)rem3
**rem**
We inject spaces when there is the danger of token
aliasing, so that we now get:
1 rem 2
(1+2)rem 3
**rem**
You can try yourself. You might need to clear your browser
cache, so that you catch the newest version:
http://www.dogelog.ch/
Mostowski Collapse schrieb am Montag, 12. Juli 2021 um 10:02:58 UTC+2:
More progress in the Unicode domain, so that we can
leave Unicode behind and move to other things. Unicode
code points, that they can represent a numeric value.
Some exotic and not so exotic examples are seen here:
unicode_numerical_value(0x0D75, 0.75, 3/4). % No MALAYALAM FRACTION THREE QUARTERS
unicode_numerical_value(0x096C, 6.0, 6). % Nd DEVANAGARI DIGIT SIX unicode_numerical_value(0x216E, 500.0, 500). % Nl ROMAN NUMERAL FIVE HUNDRED
We decided to replicate the Character.digit() API from Java. This API only returns numeric values that are integer and that are between 0 and 35.
Otherwise the API returns -1.
Can we compress like before? Yes!
Without Numeric With Numeric
pool.size()*PARA_SIZE= 8384 8416
pool2.size()*BLOCK_SIZE= 3072 3072
MAX_BLOCK= 1088 1088
Total= 12544 12576
See also:
Preview: Unicode numeric values Prolog API. (Jekejeke) https://twitter.com/dogelogch/status/1414493706124767237
Or if you are not on Twitter, but on Facebook:
Preview: Unicode numeric values Prolog API. (Jekejeke) https://www.facebook.com/groups/dogelog
Mostowski Collapse schrieb am Sonntag, 11. Juli 2021 um 01:28:13 UTC+2:
The comressed Unicode data is in JavaScript arrays,
two two-dimensional arrays and one one-dimensional array.
This could be further Prologified:
pool(+Integer, +Integer, -Integer)
pool2(+Integer, +Integer, -Integer)
buf3(+Integer, +Integer)
But since Dogelog runtime has not yet first argument
indexing, there is no use of doing this. But code_type/2
could then be implemented as follows:
code_type(C, T) :-
I is C>>10, buf3(I, J),
K is (C>>4)/\ 0x3F, pool2(J, K, L),
M is C /\ 0xF, pool(L, M, T).
Markus Triska would use (#=)/2 instead (is)/2, and say
its bidrectional. It can be also made bidrectional
manually as follows, by prepending a further clause:
code_type(C, T) :- var(C), !,
pool(L, M, T),
pool2(J, K, L),
buf3(I, J),
C is (I<<10)+(K<<4)+M.
Disclaimer: Didn't try, just paper work.
Mostowski Collapse schrieb am Sonntag, 11. Juli 2021 um 00:56:20 UTC+2:
Was checking out what Logtalk does. They
have Prolog text here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/library/unicode_data/unicode_categories
These Prolog texts contain facts like:
unicode_category_(0x00AD, 'Cf').
unicode_category_(0x0600, 'Cf').
unicode_category_(0x0601, 'Cf').
unicode_category_(0x0602, 'Cf').
unicode_category_(0x0603, 'Cf').
unicode_category_(0x0604, 'Cf').
unicode_category_(0x06DD, 'Cf').
unicode_category_(0x070F, 'Cf').
Etc...
This might be feasible standalone, but
if we want to deliver JavaScript files
over the wire into the browser,
its possibly not a good idea to have
facts with 1114111 entries. So we
made a little Unicode compressor:
compression took 109 ms
pool.size()*PARA_SIZE= 8384
pool2.size()*BLOCK_SIZE= 3072
MAX_BLOCK= 1088
Total= 12544
The compression ratio is 1%. The
1114111 entries boil down to 12544
entries. See also:
Preview: Unicode general categories Prolog API. (Jekejeke) https://gist.github.com/jburse/03c9b3cec528288d5c29c3d8bbb986c2#gistcomment-3808667
Ok I got a prototype running for Dogelog. It now
produces the following:
/* Dogelog Runtime */
:- op(400,xfy,***).
:- op(400,fy,***).
:- X = (a***b)*c, write(X), nl.
:- X = a***b*c, write(X), nl.
:- X = (***b)*c, write(X), nl.
:- X = ***b*c, write(X), nl.
(a***b)*c
a***b*c
(***b)*c
***b*c
Will upload it later. Was also testing the prefix case in
TauProlog and found a bug:
/* TauProlog */
?- X = (***b)*c.
X = *** b*c.
?- X = (***b)*c, Y = *** b*c, X = Y.
false
So it shows me something written, which I cannot re-read
to get something structurally equivalent.
The fy yfx case doesn't write correctly, so that it can be re-read https://github.com/tau-prolog/tau-prolog/issues/259
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:09:44 UTC+2:
Currently working on the final context flag that we
need in Dogelog Runtime. We need to port the SPEZ_LEFT
context flag from Jekejeke Prolog to the Dogelog Runtime.
Its for a test case that doesn't work correctly in SWI-Prolog:
Shouldn’t two structurally different Prolog terms
give a different output?
/* SWI-Prolog 8.3.26 */
?- op(400,xfy,***).
true.
?- X=(a***b)*c, Y=a***(b*c).
X = a***b*c,
Y = a***b*c.
?- X=(a***b)*c, Y=a***(b*c), X=Y.
false.
TauProlog does it correctly, but a little too cautious, it always
places parenthesis. GNU Prolog and Jekejeke Prolog are a little
less cautious, and place only parenthesis in one case:
/* GNU Prolog 1.4.5 (64 bits) */
?- X=(a***b)*c, Y=a***(b*c).
X = (a***b)*c
Y = a***b*c
We now need to reimplement for Dogelog Runtime:
if (arity == 2 && (oper = Pl_Lookup_Oper(functor, INFIX)))
{
if (oper->prec > prec || (context == INSIDE_LEFT_ASSOC_OP &&
(oper->prec == oper->right
&& oper->prec == prec)) )
{ /* prevent also the case: T xfy U yf(x) */
Out_Char('(');
bracket = TRUE;
}
https://github.com/didoudiaz/gprolog/blob/master/src/BipsPl/write_supp.c#L1069
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:03:30 UTC+2:
But then the journey was not over, we had also to
handle these cases, which are not handled through
token aliasing detecting, but through context flags:
:- X = (-) - -, write(X), nl.
:- X = - - -, write(X), nl.
:- X = - (a,b,c), write(X), nl.
:- X = -(a,b,c), write(X), nl.
:- X = - 1, write(X), nl.
:- X = -1, write(X), nl.
(-)- -
- - -
- (a, b, c)
-(a, b, c)
- 1
-1
The relevant context flags now also implemented
by Dogelog Runtime directly in Prolog, formerly found
in Jekejeke Prolog implemented in Java:
- SPEZ_OPER: 1 for (-)- - versus - - -
- SPEZ_FUNC: 2 for - (a, b, c) versus -(a, b, c)
- SPEZ_MINS: 4 for - 1 versus -1
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 10:57:28 UTC+2:
Using the compressed unicode now for:
- detecting whether an atom needs quote
- detecting whether tokens alias during writing
We do it slightly different than in Jekejeke Prolog, without a word break 2 dimensional matrice. The word break 2 dimensional matrice seems to be not anymore needed, only a few cases are relevant,
which can be directly coded as Prolog predicates:
is_name is_name
is_symbol is_symbol
\' \'
After a journey into enhancing write_term/1, the compact
writing of operators now does not give anymore:
:- X = 1 rem 2, write(X), nl.
:- X = (1+2) rem 3, write(X), nl.
:- X = ** rem **, write(X), nl.
1rem2
(1+2)rem3
**rem**
We inject spaces when there is the danger of token
aliasing, so that we now get:
1 rem 2
(1+2)rem 3
**rem**
You can try yourself. You might need to clear your browser
cache, so that you catch the newest version:
http://www.dogelog.ch/
Mostowski Collapse schrieb am Montag, 12. Juli 2021 um 10:02:58 UTC+2:
Currently working on the final context flag that we
need in Dogelog Runtime. We need to port the SPEZ_LEFT
context flag from Jekejeke Prolog to the Dogelog Runtime.
Its for a test case that doesn't work correctly in SWI-Prolog:
Shouldn’t two structurally different Prolog terms
give a different output?
/* SWI-Prolog 8.3.26 */
?- op(400,xfy,***).
true.
?- X=(a***b)*c, Y=a***(b*c).
X = a***b*c,
Y = a***b*c.
?- X=(a***b)*c, Y=a***(b*c), X=Y.
false.
TauProlog does it correctly, but a little too cautious, it always
places parenthesis. GNU Prolog and Jekejeke Prolog are a little
less cautious, and place only parenthesis in one case:
/* GNU Prolog 1.4.5 (64 bits) */
?- X=(a***b)*c, Y=a***(b*c).
X = (a***b)*c
Y = a***b*c
We now need to reimplement for Dogelog Runtime:
if (arity == 2 && (oper = Pl_Lookup_Oper(functor, INFIX)))
{
if (oper->prec > prec || (context == INSIDE_LEFT_ASSOC_OP &&
(oper->prec == oper->right
&& oper->prec == prec)) )
{ /* prevent also the case: T xfy U yf(x) */
Out_Char('(');
bracket = TRUE;
}
https://github.com/didoudiaz/gprolog/blob/master/src/BipsPl/write_supp.c#L1069
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:03:30 UTC+2:
But then the journey was not over, we had also to
handle these cases, which are not handled through
token aliasing detecting, but through context flags:
:- X = (-) - -, write(X), nl.
:- X = - - -, write(X), nl.
:- X = - (a,b,c), write(X), nl.
:- X = -(a,b,c), write(X), nl.
:- X = - 1, write(X), nl.
:- X = -1, write(X), nl.
(-)- -
- - -
- (a, b, c)
-(a, b, c)
- 1
-1
The relevant context flags now also implemented
by Dogelog Runtime directly in Prolog, formerly found
in Jekejeke Prolog implemented in Java:
- SPEZ_OPER: 1 for (-)- - versus - - -
- SPEZ_FUNC: 2 for - (a, b, c) versus -(a, b, c)
- SPEZ_MINS: 4 for - 1 versus -1
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 10:57:28 UTC+2:
Using the compressed unicode now for:
- detecting whether an atom needs quote
- detecting whether tokens alias during writing
We do it slightly different than in Jekejeke Prolog, without a word break 2 dimensional matrice. The word break 2 dimensional matrice
seems to be not anymore needed, only a few cases are relevant,
which can be directly coded as Prolog predicates:
is_name is_name
is_symbol is_symbol
\' \'
After a journey into enhancing write_term/1, the compact
writing of operators now does not give anymore:
:- X = 1 rem 2, write(X), nl.
:- X = (1+2) rem 3, write(X), nl.
:- X = ** rem **, write(X), nl.
1rem2
(1+2)rem3
**rem**
We inject spaces when there is the danger of token
aliasing, so that we now get:
1 rem 2
(1+2)rem 3
**rem**
You can try yourself. You might need to clear your browser
cache, so that you catch the newest version:
http://www.dogelog.ch/
Mostowski Collapse schrieb am Montag, 12. Juli 2021 um 10:02:58 UTC+2:
On the other hand, the new GNU Prolog seems to work
like ever before. Everything seems to be fine:
/* GNU Prolog 1.5.0 (64 bits) */
?- X = (***b)*c.
X = (***b)*c
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 15:08:35 UTC+2:
Ok I got a prototype running for Dogelog. It now
produces the following:
/* Dogelog Runtime */
:- op(400,xfy,***).
:- op(400,fy,***).
:- X = (a***b)*c, write(X), nl.
:- X = a***b*c, write(X), nl.
:- X = (***b)*c, write(X), nl.
:- X = ***b*c, write(X), nl.
(a***b)*c
a***b*c
(***b)*c
***b*c
Will upload it later. Was also testing the prefix case in
TauProlog and found a bug:
/* TauProlog */
?- X = (***b)*c.
X = *** b*c.
?- X = (***b)*c, Y = *** b*c, X = Y.
false
So it shows me something written, which I cannot re-read
to get something structurally equivalent.
The fy yfx case doesn't write correctly, so that it can be re-read https://github.com/tau-prolog/tau-prolog/issues/259
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:09:44 UTC+2:
Currently working on the final context flag that we
need in Dogelog Runtime. We need to port the SPEZ_LEFT
context flag from Jekejeke Prolog to the Dogelog Runtime.
Its for a test case that doesn't work correctly in SWI-Prolog: Shouldn’t two structurally different Prolog terms
give a different output?
/* SWI-Prolog 8.3.26 */
?- op(400,xfy,***).
true.
?- X=(a***b)*c, Y=a***(b*c).
X = a***b*c,
Y = a***b*c.
?- X=(a***b)*c, Y=a***(b*c), X=Y.
false.
TauProlog does it correctly, but a little too cautious, it always
places parenthesis. GNU Prolog and Jekejeke Prolog are a little
less cautious, and place only parenthesis in one case:
/* GNU Prolog 1.4.5 (64 bits) */
?- X=(a***b)*c, Y=a***(b*c).
X = (a***b)*c
Y = a***b*c
We now need to reimplement for Dogelog Runtime:
if (arity == 2 && (oper = Pl_Lookup_Oper(functor, INFIX)))
{
if (oper->prec > prec || (context == INSIDE_LEFT_ASSOC_OP &&
(oper->prec == oper->right
&& oper->prec == prec)) )
{ /* prevent also the case: T xfy U yf(x) */
Out_Char('(');
bracket = TRUE;
}
https://github.com/didoudiaz/gprolog/blob/master/src/BipsPl/write_supp.c#L1069
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:03:30 UTC+2:
But then the journey was not over, we had also to
handle these cases, which are not handled through
token aliasing detecting, but through context flags:
:- X = (-) - -, write(X), nl.
:- X = - - -, write(X), nl.
:- X = - (a,b,c), write(X), nl.
:- X = -(a,b,c), write(X), nl.
:- X = - 1, write(X), nl.
:- X = -1, write(X), nl.
(-)- -
- - -
- (a, b, c)
-(a, b, c)
- 1
-1
The relevant context flags now also implemented
by Dogelog Runtime directly in Prolog, formerly found
in Jekejeke Prolog implemented in Java:
- SPEZ_OPER: 1 for (-)- - versus - - -
- SPEZ_FUNC: 2 for - (a, b, c) versus -(a, b, c)
- SPEZ_MINS: 4 for - 1 versus -1
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 10:57:28 UTC+2:
Using the compressed unicode now for:
- detecting whether an atom needs quote
- detecting whether tokens alias during writing
We do it slightly different than in Jekejeke Prolog, without a word break 2 dimensional matrice. The word break 2 dimensional matrice seems to be not anymore needed, only a few cases are relevant,
which can be directly coded as Prolog predicates:
is_name is_name
is_symbol is_symbol
\' \'
After a journey into enhancing write_term/1, the compact
writing of operators now does not give anymore:
:- X = 1 rem 2, write(X), nl.
:- X = (1+2) rem 3, write(X), nl.
:- X = ** rem **, write(X), nl.
1rem2
(1+2)rem3
**rem**
We inject spaces when there is the danger of token
aliasing, so that we now get:
1 rem 2
(1+2)rem 3
**rem**
You can try yourself. You might need to clear your browser
cache, so that you catch the newest version:
http://www.dogelog.ch/
Mostowski Collapse schrieb am Montag, 12. Juli 2021 um 10:02:58 UTC+2:
The closest to what I am testing is possibly Ulrich Neumerkels
#152 and #153. But this tests only the writing of fy yfx, on not
the writing of xfy yfx. I don’t find tests for the later.
Conformity Testing I: Syntax https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#152 Conformity Testing I: Syntax https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#153
Interestingly the TauProlog bug is #152 and #153. One can
verify that we now have as expected output:
:- op(9,fy,fy).
:- op(9,yfx,yfx).
:- writeq(fy(yfx(1,2))), nl.
:- writeq(yfx(fy(1),2)), nl.
fy 1 yfx 2
(fy 1)yfx 2
But for Tau Prolog I get:
fy (1 yfx 2)
fy 1 yfx 2
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 15:10:04 UTC+2:
On the other hand, the new GNU Prolog seems to work
like ever before. Everything seems to be fine:
/* GNU Prolog 1.5.0 (64 bits) */
?- X = (***b)*c.
X = (***b)*c
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 15:08:35 UTC+2:
Ok I got a prototype running for Dogelog. It now
produces the following:
/* Dogelog Runtime */
:- op(400,xfy,***).
:- op(400,fy,***).
:- X = (a***b)*c, write(X), nl.
:- X = a***b*c, write(X), nl.
:- X = (***b)*c, write(X), nl.
:- X = ***b*c, write(X), nl.
(a***b)*c
a***b*c
(***b)*c
***b*c
Will upload it later. Was also testing the prefix case in
TauProlog and found a bug:
/* TauProlog */
?- X = (***b)*c.
X = *** b*c.
?- X = (***b)*c, Y = *** b*c, X = Y.
false
So it shows me something written, which I cannot re-read
to get something structurally equivalent.
The fy yfx case doesn't write correctly, so that it can be re-read https://github.com/tau-prolog/tau-prolog/issues/259
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:09:44 UTC+2:
Currently working on the final context flag that we
need in Dogelog Runtime. We need to port the SPEZ_LEFT
context flag from Jekejeke Prolog to the Dogelog Runtime.
Its for a test case that doesn't work correctly in SWI-Prolog: Shouldn’t two structurally different Prolog terms
give a different output?
/* SWI-Prolog 8.3.26 */
?- op(400,xfy,***).
true.
?- X=(a***b)*c, Y=a***(b*c).
X = a***b*c,
Y = a***b*c.
?- X=(a***b)*c, Y=a***(b*c), X=Y.
false.
TauProlog does it correctly, but a little too cautious, it always places parenthesis. GNU Prolog and Jekejeke Prolog are a little
less cautious, and place only parenthesis in one case:
/* GNU Prolog 1.4.5 (64 bits) */
?- X=(a***b)*c, Y=a***(b*c).
X = (a***b)*c
Y = a***b*c
We now need to reimplement for Dogelog Runtime:
if (arity == 2 && (oper = Pl_Lookup_Oper(functor, INFIX)))
{
if (oper->prec > prec || (context == INSIDE_LEFT_ASSOC_OP && (oper->prec == oper->right
&& oper->prec == prec)) )
{ /* prevent also the case: T xfy U yf(x) */
Out_Char('(');
bracket = TRUE;
}
https://github.com/didoudiaz/gprolog/blob/master/src/BipsPl/write_supp.c#L1069
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 11:03:30 UTC+2:
But then the journey was not over, we had also to
handle these cases, which are not handled through
token aliasing detecting, but through context flags:
:- X = (-) - -, write(X), nl.
:- X = - - -, write(X), nl.
:- X = - (a,b,c), write(X), nl.
:- X = -(a,b,c), write(X), nl.
:- X = - 1, write(X), nl.
:- X = -1, write(X), nl.
(-)- -
- - -
- (a, b, c)
-(a, b, c)
- 1
-1
The relevant context flags now also implemented
by Dogelog Runtime directly in Prolog, formerly found
in Jekejeke Prolog implemented in Java:
- SPEZ_OPER: 1 for (-)- - versus - - -
- SPEZ_FUNC: 2 for - (a, b, c) versus -(a, b, c)
- SPEZ_MINS: 4 for - 1 versus -1
Mostowski Collapse schrieb am Samstag, 17. Juli 2021 um 10:57:28 UTC+2:
Using the compressed unicode now for:
- detecting whether an atom needs quote
- detecting whether tokens alias during writing
We do it slightly different than in Jekejeke Prolog, without a word
break 2 dimensional matrice. The word break 2 dimensional matrice seems to be not anymore needed, only a few cases are relevant,
which can be directly coded as Prolog predicates:
is_name is_name
is_symbol is_symbol
\' \'
After a journey into enhancing write_term/1, the compact
writing of operators now does not give anymore:
:- X = 1 rem 2, write(X), nl.
:- X = (1+2) rem 3, write(X), nl.
:- X = ** rem **, write(X), nl.
1rem2
(1+2)rem3
**rem**
We inject spaces when there is the danger of token
aliasing, so that we now get:
1 rem 2
(1+2)rem 3
**rem**
You can try yourself. You might need to clear your browser
cache, so that you catch the newest version:
http://www.dogelog.ch/
Mostowski Collapse schrieb am Montag, 12. Juli 2021 um 10:02:58 UTC+2:
Was checking out what Logtalk does. They
have Prolog text here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/library/unicode_data/unicode_categories
These Prolog texts contain facts like:
unicode_category_(0x00AD, 'Cf').
unicode_category_(0x0600, 'Cf').
unicode_category_(0x0601, 'Cf').
unicode_category_(0x0602, 'Cf').
unicode_category_(0x0603, 'Cf').
unicode_category_(0x0604, 'Cf').
unicode_category_(0x06DD, 'Cf').
unicode_category_(0x070F, 'Cf').
Etc...
This might be feasible standalone, but
if we want to deliver JavaScript files
over the wire into the browser,
its possibly not a good idea to have
facts with 1114111 entries. So we
made a little Unicode compressor:
compression took 109 ms
pool.size()*PARA_SIZE= 8384
pool2.size()*BLOCK_SIZE= 3072
MAX_BLOCK= 1088
Total= 12544
The compression ratio is 1%. The
1114111 entries boil down to 12544
entries. See also:
Preview: Unicode general categories Prolog API. (Jekejeke) https://gist.github.com/jburse/03c9b3cec528288d5c29c3d8bbb986c2#gistcomment-3808667
Dogelog runtime currently quaranteens the '.'
operator. Unlike Jekejeke Prolog which had this
solution for the '.' operator:
:- op(200, xfy, '.').
:- set_oper_property(infix('.'), sys_alias(sys_dot)).
:- op(200, xfy, sys_dot).
:- set_oper_property(infix(sys_dot), sys_portray('.')).
But we have now adopted most of the Dogelog runtime
parsing and unparsing strategies also in Jekejeke Prolog,
we now get in Jekejeke Prolog:
?- X = foo.bar.
X = foo'.'bar
The old expected output is foo.bar. We should find a
heuristic to make writing of the '.' operator more compact.
Picat seems to use the '.' operator for message sending.
How do they solve it?
Mostowski Collapse schrieb:
Was checking out what Logtalk does. They
have Prolog text here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/library/unicode_data/unicode_categories
These Prolog texts contain facts like:
unicode_category_(0x00AD, 'Cf').
unicode_category_(0x0600, 'Cf').
unicode_category_(0x0601, 'Cf').
unicode_category_(0x0602, 'Cf').
unicode_category_(0x0603, 'Cf').
unicode_category_(0x0604, 'Cf').
unicode_category_(0x06DD, 'Cf').
unicode_category_(0x070F, 'Cf').
Etc...
This might be feasible standalone, but
if we want to deliver JavaScript files
over the wire into the browser,
its possibly not a good idea to have
facts with 1114111 entries. So we
made a little Unicode compressor:
compression took 109 ms
pool.size()*PARA_SIZE= 8384
pool2.size()*BLOCK_SIZE= 3072
MAX_BLOCK= 1088
Total= 12544
The compression ratio is 1%. The
1114111 entries boil down to 12544
entries. See also:
Preview: Unicode general categories Prolog API. (Jekejeke) https://gist.github.com/jburse/03c9b3cec528288d5c29c3d8bbb986c2#gistcomment-3808667
Some crucial problems are number aliasing or symbol aliasing.
The following test cases would go wrong without the quotes.
We now find for example:
?- X = (1).(2).
X = 1'.'2
?- X = (===).(===).
X = ==='.'===
These test case would go wrong also via safe_space/3, since
inserting a space would turn the '.' operator into a terminating
period. And not inserting a space gives a wrong result.
So maybe an approach would be inserting parenthesis?
Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 15:00:03 UTC+2:
Dogelog runtime currently quaranteens the '.'
operator. Unlike Jekejeke Prolog which had this
solution for the '.' operator:
:- op(200, xfy, '.').
:- set_oper_property(infix('.'), sys_alias(sys_dot)).
:- op(200, xfy, sys_dot).
:- set_oper_property(infix(sys_dot), sys_portray('.')).
But we have now adopted most of the Dogelog runtime
parsing and unparsing strategies also in Jekejeke Prolog,
we now get in Jekejeke Prolog:
?- X = foo.bar.
X = foo'.'bar
The old expected output is foo.bar. We should find a
heuristic to make writing of the '.' operator more compact.
Picat seems to use the '.' operator for message sending.
How do they solve it?
Mostowski Collapse schrieb:
Was checking out what Logtalk does. They
have Prolog text here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/library/unicode_data/unicode_categories
These Prolog texts contain facts like:
unicode_category_(0x00AD, 'Cf').
unicode_category_(0x0600, 'Cf').
unicode_category_(0x0601, 'Cf').
unicode_category_(0x0602, 'Cf').
unicode_category_(0x0603, 'Cf').
unicode_category_(0x0604, 'Cf').
unicode_category_(0x06DD, 'Cf').
unicode_category_(0x070F, 'Cf').
Etc...
This might be feasible standalone, but
if we want to deliver JavaScript files
over the wire into the browser,
its possibly not a good idea to have
facts with 1114111 entries. So we
made a little Unicode compressor:
compression took 109 ms
pool.size()*PARA_SIZE= 8384
pool2.size()*BLOCK_SIZE= 3072
MAX_BLOCK= 1088
Total= 12544
The compression ratio is 1%. The
1114111 entries boil down to 12544
entries. See also:
Preview: Unicode general categories Prolog API. (Jekejeke) https://gist.github.com/jburse/03c9b3cec528288d5c29c3d8bbb986c2#gistcomment-3808667
The same test cases go wrong in SWI-Prolog:
/* SWI-Prolog 8.3.26 */
?- read(X), write_canonical(X), nl.
|: (1).(2).
'.'(1,2)
X = 1.2.
?- read(X), write_canonical(X), nl.
|: (===).(===).
'.'(===,===)
X = === . === .
Re-reading 1.2. or === . === . gives a different result
than the Prolog term that was written.
Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 15:09:08 UTC+2:
Some crucial problems are number aliasing or symbol aliasing.
The following test cases would go wrong without the quotes.
We now find for example:
?- X = (1).(2).
X = 1'.'2
?- X = (===).(===).
X = ==='.'===
These test case would go wrong also via safe_space/3, since
inserting a space would turn the '.' operator into a terminating
period. And not inserting a space gives a wrong result.
So maybe an approach would be inserting parenthesis?
Mostowski Collapse schrieb am Freitag, 23. Juli 2021 um 15:00:03 UTC+2:
Dogelog runtime currently quaranteens the '.'
operator. Unlike Jekejeke Prolog which had this
solution for the '.' operator:
:- op(200, xfy, '.').
:- set_oper_property(infix('.'), sys_alias(sys_dot)).
:- op(200, xfy, sys_dot).
:- set_oper_property(infix(sys_dot), sys_portray('.')).
But we have now adopted most of the Dogelog runtime
parsing and unparsing strategies also in Jekejeke Prolog,
we now get in Jekejeke Prolog:
?- X = foo.bar.
X = foo'.'bar
The old expected output is foo.bar. We should find a
heuristic to make writing of the '.' operator more compact.
Picat seems to use the '.' operator for message sending.
How do they solve it?
Mostowski Collapse schrieb:
Was checking out what Logtalk does. They
have Prolog text here:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/library/unicode_data/unicode_categories
These Prolog texts contain facts like:
unicode_category_(0x00AD, 'Cf').
unicode_category_(0x0600, 'Cf').
unicode_category_(0x0601, 'Cf').
unicode_category_(0x0602, 'Cf').
unicode_category_(0x0603, 'Cf').
unicode_category_(0x0604, 'Cf').
unicode_category_(0x06DD, 'Cf').
unicode_category_(0x070F, 'Cf').
Etc...
This might be feasible standalone, but
if we want to deliver JavaScript files
over the wire into the browser,
its possibly not a good idea to have
facts with 1114111 entries. So we
made a little Unicode compressor:
compression took 109 ms
pool.size()*PARA_SIZE= 8384
pool2.size()*BLOCK_SIZE= 3072
MAX_BLOCK= 1088
Total= 12544
The compression ratio is 1%. The
1114111 entries boil down to 12544
entries. See also:
Preview: Unicode general categories Prolog API. (Jekejeke) https://gist.github.com/jburse/03c9b3cec528288d5c29c3d8bbb986c2#gistcomment-3808667
But reach_notoken will go down the drain,
when the tokenizer does handle '.' the new
way. Only recogizing it, not consuming it.
Thats an interesting find. Most Prolog system
don't implement the ISO terminating period. For
example TauProlog 0.3.1 (beta) accepts this Prolog text:
foo(bar).foo(baz).
When I run a query I get:
?- foo(X), write(X), nl, fail; true.
bar
baz
On the other hand ECLiPSe Prolog doesn't accept it,
similarly GNU Prolog, it also emits the operator error:
[eclipse 1]: [user].
foo(bar).foo(baz).
syntax error: postfix/infix operator expected
| foo(bar).foo(baz).
| ^ here
SWI-Prolog accepts it, but barks otherwise:
?- [user].
|: foo(bar).foo(baz).
ERROR: user://1:8:
ERROR: Arguments are not sufficiently instantiated
YAP Prolog silently swallows it:
?- [user].
% consulting user_output...
| foo(bar).foo(baz).
|
% consulted user_output in module user, 15 msec 0 bytes
yes
?- foo(X), write(X), nl, fail; true.
ERROR!!
EXISTENCE ERROR- procedure foo/1 is undefined, called from context
prolog:$command/4
Goal was user:foo(_131502)
But the TauProlog behaviour leads me to a
new implementation of the period, that I have
never done before.
The Tokenizer would recognize ., but not consume
it. This is different from the ISO core specification
that says recognize and consume ., and then
recognize white or % line comment without the
eoln or eof. To only recognize white or % line
comment allows implementation without the
requirement that the input stream allows push
back. The new approach that only recognizes .
does also not require an input stream that allows
push back, but we will need peek code.
Mostowski Collapse schrieb:
Thats an interesting find. Most Prolog system
don't implement the ISO terminating period. For
example TauProlog 0.3.1 (beta) accepts this Prolog text:
foo(bar).foo(baz).
When I run a query I get:
?- foo(X), write(X), nl, fail; true.
bar
baz
On the other hand ECLiPSe Prolog doesn't accept it,
similarly GNU Prolog, it also emits the operator error:
[eclipse 1]: [user].
foo(bar).foo(baz).
syntax error: postfix/infix operator expected
| foo(bar).foo(baz).
| ^ here
SWI-Prolog accepts it, but barks otherwise:
?- [user].
|: foo(bar).foo(baz).
ERROR: user://1:8:
ERROR: Arguments are not sufficiently instantiated
YAP Prolog silently swallows it:
?- [user].
% consulting user_output...
| foo(bar).foo(baz).
|
% consulted user_output in module user, 15 msec 0 bytes
yes
?- foo(X), write(X), nl, fail; true.
ERROR!!
EXISTENCE ERROR- procedure foo/1 is undefined, called from
context prolog:$command/4
Goal was user:foo(_131502)
trueSo we need to fix that as well.
Looks like we misinterpreted how arithmetic comparison
works in JavaScript. Its not possible to use (==) from JavaScript
and (<) from JavaScript directly for Prolog (=:=) and Prolog (<).
The last two test cases are wrong:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
no
no
yes
The explanation is that JavaScript promotes to BigInt if one
of the arguments is BigInt. But the Prolog semantics would be
rather to promote to float when one of the arguments is float.
Here is how the last test case can be explained:
console.log(30000000000000000000000000n < BigInt(30000000000000000000000000.1));
trueSo we need to fix that as well.
570425344n
We could fix the arithmetic comparison.
The results are now correct:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
But not all Prolog systems agree. The Prolog systems that agree
is for example Jekejeke Prolog. In Jekejeke Prolog I find:
/* Jekejeke Prolog 1.5.1 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
No
But SWI-Prolog and ECLiPSe Prolog do not agree:
/* SWI-Prolog 8.3.26 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
true.
/* ECLiPSe Version 7.0 #54 */
[eclipse 2]: 30000000000000000000000000 < 30000000000000000000000000.1.
Yes (0.00s cpu)
Mostowski Collapse schrieb am Mittwoch, 28. Juli 2021 um 23:38:37 UTC+2:
Looks like we misinterpreted how arithmetic comparison
works in JavaScript. Its not possible to use (==) from JavaScript
and (<) from JavaScript directly for Prolog (=:=) and Prolog (<).
The last two test cases are wrong:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
no
no
yes
The explanation is that JavaScript promotes to BigInt if one
of the arguments is BigInt. But the Prolog semantics would be
rather to promote to float when one of the arguments is float.
Here is how the last test case can be explained:
console.log(30000000000000000000000000n < BigInt(30000000000000000000000000.1));
trueSo we need to fix that as well.
The discrepancy in SWI-Prolog and ECLiPSe Prolog is
due to low fidelity float/1 conversion. One can try the
following in SWI-Prolog and ECLiPSe Prolog:
/* SWI-Prolog 8.3.26 */
?- X is float(30000000000000000000000000).
X = 2.9999999999999996e+25.
?- X is integer(float(30000000000000000000000000))-30000000000000000000000000.
X = -3724541952.
/* ECLiPSe Version 7.0 #54 */
[eclipse 1]: X is float(30000000000000000000000000).
X = 2.9999999999999996e+25
So the propose to approximate the integer value by
the float 2.9999999999999996e+25, which is -3724541952
away from the integer.
Lets see what JavaScript does, it proposes a different
float number, which is closer to the integer. abs(-3724541952)
is larger than abs(570425344):
console.log(BigInt(Number(30000000000000000000000000n))- 30000000000000000000000000n);
570425344n
So JavaScript has high fidelity float/1, like Jekejeke Prolog.
This explains the different outcome in Prolog (<). Dogelog
runtime now uses the JavaScript high fidelity float/1 as
well and therefore has the same outcome as Jekejeke Prolog.
Mostowski Collapse schrieb am Mittwoch, 28. Juli 2021 um 23:45:38 UTC+2:
We could fix the arithmetic comparison.
The results are now correct:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
But not all Prolog systems agree. The Prolog systems that agree
is for example Jekejeke Prolog. In Jekejeke Prolog I find:
/* Jekejeke Prolog 1.5.1 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
No
But SWI-Prolog and ECLiPSe Prolog do not agree:
/* SWI-Prolog 8.3.26 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
true.
/* ECLiPSe Version 7.0 #54 */
[eclipse 2]: 30000000000000000000000000 < 30000000000000000000000000.1.
Yes (0.00s cpu)
Mostowski Collapse schrieb am Mittwoch, 28. Juli 2021 um 23:38:37 UTC+2:
Looks like we misinterpreted how arithmetic comparison
works in JavaScript. Its not possible to use (==) from JavaScript
and (<) from JavaScript directly for Prolog (=:=) and Prolog (<).
The last two test cases are wrong:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
no
no
yes
The explanation is that JavaScript promotes to BigInt if one
of the arguments is BigInt. But the Prolog semantics would be
rather to promote to float when one of the arguments is float.
Here is how the last test case can be explained:
console.log(30000000000000000000000000n < BigInt(30000000000000000000000000.1));
trueSo we need to fix that as well.
We could fix the arithmetic comparison.
The results are now correct:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
But not all Prolog systems agree. The Prolog systems that agree
is for example Jekejeke Prolog. In Jekejeke Prolog I find:
/* Jekejeke Prolog 1.5.1 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
No
But SWI-Prolog and ECLiPSe Prolog do not agree:
/* SWI-Prolog 8.3.26 */
?- 30000000000000000000000000 < 30000000000000000000000000.1.
true.
/* ECLiPSe Version 7.0 #54 */
[eclipse 2]: 30000000000000000000000000 < 30000000000000000000000000.1.
Yes (0.00s cpu)
Mostowski Collapse schrieb am Mittwoch, 28. Juli 2021 um 23:38:37 UTC+2:
Looks like we misinterpreted how arithmetic comparison
works in JavaScript. Its not possible to use (==) from JavaScript
and (<) from JavaScript directly for Prolog (=:=) and Prolog (<).
The last two test cases are wrong:
:- 1 == 1.0, write(yes), nl; write(no), nl.
:- 1 =:= 1.0, write(yes), nl; write(no), nl.
:- 30000000000000000000000000 < 30000000000000000000000000.1,
write(yes), nl; write(no), nl.
no
no
yes
The explanation is that JavaScript promotes to BigInt if one
of the arguments is BigInt. But the Prolog semantics would be
rather to promote to float when one of the arguments is float.
Here is how the last test case can be explained:
console.log(30000000000000000000000000n < BigInt(30000000000000000000000000.1));
trueSo we need to fix that as well.
I just tried:
Picat 3.1, (C) picat-lang.org, 2013-2021.
Picat> X is float(30000000000000000000000000).
*** Undefined procedure: float/1
So float/1 doesn't exist. What am I supposed to do?
This here seems to be a work around though?
Picat> X is 30000000000000000000000000+0.0.
X = 30000000000000000570425344.0
yes
It is even correct! (Tested on Mac)
But I guess it would be legit to show it automatically
in scientific form, since there is no ambiguity in re-read
when shown as follows (Dogelog runtime output):
:- X is 30000000000000000000000000+0.0, write(X), nl.
3.0E25
Yes, such an output would also work in Picat:
Picat> X is 3.0E25.
X = 30000000000000000570425344.0
yes
Its the same float.
Mostowski Collapse schrieb am Donnerstag, 29. Juli 2021 um 13:46:31 UTC+2:
I just tried:
Picat 3.1, (C) picat-lang.org, 2013-2021.
Picat> X is float(30000000000000000000000000).
*** Undefined procedure: float/1
So float/1 doesn't exist. What am I supposed to do?
This here seems to be a work around though?
Picat> X is 30000000000000000000000000+0.0.
X = 30000000000000000570425344.0
yes
It is even correct! (Tested on Mac)
30000000000000000570425344int(float(30000000000000000000000000))
TauProlog 0.3.1 (beta)
?- number_chars(X,"30000000000000000000000000").
X = 3.
?- X is 30000000000000000000000000.
X = 3.
Was rather expecting an overflow error, because of the flag value:
?- current_prolog_flag(bounded, X).
X = true
Mostowski Collapse schrieb am Donnerstag, 29. Juli 2021 um 13:47:49 UTC+2:
But I guess it would be legit to show it automatically
in scientific form, since there is no ambiguity in re-read
when shown as follows (Dogelog runtime output):
:- X is 30000000000000000000000000+0.0, write(X), nl.
3.0E25
Yes, such an output would also work in Picat:
Picat> X is 3.0E25.
X = 30000000000000000570425344.0
yes
Its the same float.
Mostowski Collapse schrieb am Donnerstag, 29. Juli 2021 um 13:46:31 UTC+2:
I just tried:
Picat 3.1, (C) picat-lang.org, 2013-2021.
Picat> X is float(30000000000000000000000000).
*** Undefined procedure: float/1
So float/1 doesn't exist. What am I supposed to do?
This here seems to be a work around though?
Picat> X is 30000000000000000000000000+0.0.
X = 30000000000000000570425344.0
yes
It is even correct! (Tested on Mac)
Maybe I should do more testing, JavaScript describes the method to find a float as HALFEVEN. I guess this method applied when one calls the conversion Number(), i.e. the constructor without the new keyword, which is the float/1 evaluable
function equivalent of JavaScript. The conversion Number() can be also called for bigint arguments. So JavaScript has float/1 from a bigint like Prolog does have. So how is this conversion described:
" In this specification, the phrase “the Number value for x” where x represents an exact real mathematical quantity (which might even be
an irrational number such as π) means a Number value chosen in the following manner. Consider the set of all finite values of the Number type, with -0𝔽 removed and with two additional values added to it that are not representable in the Number type, namely 2^1024 (which is +1 × 253 × 2971) and -2^1024 (which is -1 × 253 × 2971). Choose the member of this set that is closest in value to x. If two values of the set are equally close, then the
one with an even significand is chosen; for this purpose, the two extra values
2^1024 and -2^1024 are considered to have even significands. Finally, if 2^1024
was chosen, replace it with +∞𝔽; if -21024 was chosen, replace it with -∞𝔽;
if +0𝔽 was chosen, replace it with -0𝔽 if and only if x < 0; any other chosen
value is used unchanged. The result is the Number value for x. (This procedure
corresponds exactly to the behaviour of the IEEE 754-2019 roundTiesToEven mode.)"
https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type
I am not sure whether I tested this already. The current test doesn’t test a tie.
Creating a tie test case is a tick more work. Also the above describes a choice of negative zero. I should convert negative zero into positive zero in my system, since I do not want to support that, its currently not in the ISO core standard. But SWI-Prolog might support it:
/* SWI-Prolog 8.3.26 */
?- X is -0.0.
X = -0.0.
Now there are some interesting news, we might soon
see SWI-Prolog performing the following feat:
?- A = ४२.
A = 42.
This works already for a while in Dogelog, although
it had a bug, which was only fixed yesterday.
You can try: http://www.xlog.ch/izytab/moblet/docs/18_live/10_reference/example01/package.html
One could further extend it to Hex. Like for example:
?- A = 0xBABE.
A = 47806.
Works in Dogelog Player and formerly Jekejeke Prolog.
Again I only did it because Java can already do it.
Take this Java code:
int val = Integer.parseInt("BABE", 16); System.out.println("val="+val);
It gives me:
val=47806
Mostowski Collapse schrieb am Freitag, 24. Juni 2022 um 10:24:47 UTC+2:
Now there are some interesting news, we might soon
see SWI-Prolog performing the following feat:
?- A = ४२.
A = 42.
This works already for a while in Dogelog, although
it had a bug, which was only fixed yesterday.
You can try: http://www.xlog.ch/izytab/moblet/docs/18_live/10_reference/example01/package.html
Microsoft compilers and interpreters, and many pieces of software
on Microsoft Windows such as Notepad treat the BOM as a required
magic number rather than use heuristics. These tools add a BOM when
saving text as UTF-8, and cannot interpret UTF-8 unless the BOM is
present or the file contains only ASCII. https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
Now I am picking up new vibes for Dogelog Player, its still
a young Prolog system, and the streams are also still pretty
primitive. Maybe some new ideas might even spill back
to formerly Jekejeke Prolog. So whats on the todo list next?
I find that the following goodies concerning open/4 are missing,
its even the case that we even only have an open/3 so far:
- bom(Bool)
Specify detecting or writing a BOM.
- encoding(Atom)
Specify a file encoding.
BTW: This is an interesting read:
Microsoft compilers and interpreters, and many pieces of software
on Microsoft Windows such as Notepad treat the BOM as a required
magic number rather than use heuristics. These tools add a BOM when
saving text as UTF-8, and cannot interpret UTF-8 unless the BOM is
present or the file contains only ASCII. https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
So you might find a BOM also for UTF-8 files, not only UTF-16 and other encodings. The usual heuristic is to choose UTF-8 if there is no BOM, but the above suggests to throw an error if there is no BOM
and some non-ASCII, i.e. > 7 bit.
Q: Why did Prolog miss the OpenAI/ChatGPT bandwagon?
A: Its in the genetics, Prolog is developing backwards:
1) Quintus: library(charsio)
2) SICStus: Na, library(codesio), characters that are atoms
of length 1 could pollute the atom table.
3.1) Scryer Prolog: Na, library(charsio), we have to go backwards,
create a vintage Prolog.
Just notice I made a big mistake, or maybe not? I used the following
syntax for reference data type in Prolog:
reference :== "0" "r" name .
Isn’t this in conflict to rational numbers syntax:
rational :== integer "r" integer .
Not really a rational number would have a digit after “r”, whereas
a reference data type wouldn’t have a digit after the “r”.
Now I can input output the beasts on JavaScript and Python,
and even sorting them now works:
?- sort([1,0rFalse,3.14,0rNone], L).
L = [3.14, 1, 0rNone, 0rFalse].
?- compound(0rTrue).
fail.
?- reference(0rTrue).
true.
Note: Do not confuse multillingual strings, as introduced
by recent Dogelog Player, with Unicode encoding.
I am using the phrase "multilingual strings" for a text
database. Interestingly I managed to make the text
database declarative. Means the strings/3 entries
are not order dependent. You can place languages into
the multifile predicate in any order,
and it will pick the most specific string independent
of the order of the strings/3 facts. I was replicating
the Java Script Resource Bundle lookup on a finer
grained level, by this simple Prolog code:
get_string(Key, Locale, Value) :-
sys_locale_ancestor(Locale, Parent),
strings(Key, Parent, Res), !,
Value = Res.
% sys_locale_ancestor(+Atom, -Atom)
sys_locale_ancestor(L, L).
sys_locale_ancestor(L, M) :-
last_sub_atom(L, P, _, _, '_'),
sub_atom(L, 0, P, _, M).
sys_locale_ancestor(_, '').
The above assumes that locale identifiers use
underscore separator. It also assumes the last_sub_atom/3
predicate from Novacore, unfortunatel ISO Core has
only sub_atom/3, but no last_sub_atom/3.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (2 / 14) |
Uptime: | 63:43:07 |
Calls: | 6,654 |
Files: | 12,200 |
Messages: | 5,331,702 |