How is a integer created as a character code constant? - prolog

I am building some test cases for integer/1 using SWI-Prolog.
ISO/IEC 13211-1 gives a BNF definition for integer and one of the alternatives for integer is for a character code constant.
I am able to create and test examples of all the other alternatives using integer/1 but for character code constant I cannot create a valid example. (see below)
How is an integer as a character code constant created that will return true using integer/1?
Answer
Thanks to #false.
integer(0'0).
true.
integer(0'9).
true.
integer(0'a).
true.
integer(0'\n).
true.
Usefulness
X is 0'\n.
X = 10.
X is 0b010101.
X = 21.
X is 0xFFF1.
X = 65521.
X is 0o7423.
X = 3859.
and thanks to j4n bur53 via link from #false
with SWI-Prolog other radix can be used besides 2,8, or 16.
X is 5'1234012340.
X = 3032220.
X is 32'123456789ABCDEFGHIJKLMNOPQRSTU.
X = 47525417447024678661670292427038339608998846.
What I tried
integer("0").
false.
integer('0').
false.
integer(`0`).
false.
integer("1").
false.
integer('1').
false.
integer(`1`).
false.
ISO
INTERNATIONAL STANDARD ISO/IEC 13211-1 First edition 1995-06-01
Information technology - Programming languages - Prolog
Part 1: General Core
INTERNATIONAL STANDARD ISO/IEC 13211-1:1995
TECHNICAL CORRIGENDUM 1
Published 2007-11-15
INTERNATIONAL STANDARD ISO/IEC 13211-1:1995
TECHNICAL CORRIGENDUM 2
Published 2012-02-15
BNF for integer
integer token (* 6.4.4 *) =
integer constant (* 6.4.4 *)
| character code constant (* 6.4.4 *)
| binary constant (* 6.4.4 *)
| octal constant (* 6.4.4 *)
| hexadecimal constant (* 6.4.4 *) ;
BNF for character code constant
character code constant (* 6.4.4 *) =
"0" , single quote char (* 6.5.5 *), single quoted character (* 6.4.2.1 *)
I suspect the BNF is wrong in ISO/IEC 13211-1 but checking the CORRIGENDUM shows no corrections.
Integer test cases
% <integer constant> examples
number(1).
% true.
number(0).
% true.
number(01).
% true.
number(12345678901234567890123456789012345678901234567890).
% true.
% <character code constant> examples
% ???
% <binary constant> examples
number(0b0).
% true.
number(0b10101010101010101010101010101010101010101010101010).
% true.
integer(0b2).
% ERROR: Syntax error: Illegal number
% ERROR: integer
% ERROR: ** here **
% ERROR: (0b2) .
% <octal constant> examples
integer(0o7).
% true.
integer(0o1234567012345670123456701234567012345670123456701234567).
% true.
integer(0o8).
% ERROR: Syntax error: Illegal number
% ERROR: integer
% ERROR: ** here **
% ERROR: (0o8) .
% <hexadecimal constant>
integer(0x0).
% true.
integer(0xF).
% true.
integer(0xf).
% true.
integer(0x123456789ABCDEF012345670123456789ABCDEF012345670123456789ABCDEF).
% true.
integer(0xG).
% ERROR: Syntax error: Illegal number
% ERROR: integer
% ERROR: ** here **
% ERROR: (0xG) .

This was answered by false in a comment.
Reposting here so that others can see an answer exist.
integer(0'0).
true.
integer(0'9).
true.
integer(0'a).
true.
integer(0'\n).
true.

Related

What does a caret before an int mean?

I'm aware the caret symbol ^ means bitwise XOR
but I'm looking at a pice of Go code and I see things like
input[0] = ^output[3]
when I try for example:
^1 gives -2
^2 gives -3
etc..
From the "Arithmetic Operators" section of the language specification:
For integer operands, the unary operators +, -, and ^ are defined as
follows:
+x is 0 + x
-x negation is 0 - x
^x bitwise complement is m ^ x with m = "all bits set to 1" for unsigned x
and m = -1 for signed x
As a unary operator it means 'bitwise not'

Trying to generate list of non-zero integers in Prolog

I'm trying to define the function int(?X) in prolog which is a non-zero integer number generator which works like this:
?- int(X). X = 1 ; X = -1 ; X = 2 ; X = -2 ;
I tried the following with no luck:
int(X):- positives(Y), Y is abs(X).
positives(1).
positives(X):- positives(Y), X is Y+1.
but I'm getting the following error:
ERROR: is/2: Arguments are not sufficiently instantiated
How can I make this work? Thanks!
There is an easy way to find and correct such problems.
Step one: Put clpfd constraints in your program. To do this, simply1 replace (is)/2 by the CLP(FD) constraint (#=)/2, i.e.:
int(X) :- positives(Y), Y #= abs(X).
positives(1).
positives(X):- positives(Y), X #= Y+1.
Step two: The query now completes without errors, and shows you what you are describing:
?- int(X).
X in -1\/1 ;
X in -2\/2 ;
X in -3\/3 ;
X in -4\/4 .
So, from the above, you see that what you are describing is not sufficient to obtain ground solutions: There is still a certain degree of freedom in your relations.
Step three: To actually fix the problem, we think about what we actually want to describe. Here is a start:
int(X) :- positives(Y), ( X #= Y ; X #= -Y).
Step four: We try it out:
?- int(X).
X = 1 ;
X = -1 ;
X = 2 ;
X = -2 ;
X = 3 ;
etc.
Seems to work OK, except for the fact that natural numbers are actually never negative. I leave fixing this discrepancy between the title of your question and the relation you are describing as an exercise for you.
TL;DR: When reasoning over integers, use your system's CLP(FD) constraints, then take it from there.
I am assuming that you have already put :- use_module(library(clpfd)). somewhere in your initial file, so that you can use CLP(FD) constraints in all your programs.

What does the bitwise negation operator(\) do in prolog?

I have to implement some functions, one of which is f= ~p/\~q.
I have the following :
p(a). p(b).
q(a). q(b). q(c).
I found the function as:
f(X):-p(\X);q(\X).
When I verify it ( f(X). , f(a). , f(b). , f(c). ) it always returns false.
Shouldn't it return true for c since c is not of type p?
Thank you!
(\)/1 is an evaluable functor for bitwise complement. If you use it directly in an argument, it is only an uninterpreted functor. Evaluation is only performed with (is)/2, (>)/2 and other comparison operators.
In all current Prolog implementations you get:
?- X is \ 1.
X = -2.
Fine print: An ISO conforming system is free to define the value for \. That is, it is free, whether it uses 2's complement or another representation. However, there are only systems that use 2's complement.
Your implementation of that formula seems flawed.
You are required about f : (not p) and (not q)
A restricted negation is available in Prolog, using operator (\+)/1, and conjunction (X and Y) is expressed by comma i.e. (,)/2.
Semicolon i.e. (;)/2 means or, as for instance in the following test, that shows your initial assumption about f(c) is also wrong.
?- forall(member(X,[a,b,c,d]),(f(X)->writeln(y);writeln(n))).
n
n
n
y
(of course, after f/1 has been translated correctly)

what should I include in Knowledge base to tell prolog that average of 0/0 is zero to avoid zero divisor?

this is the facts I entered in the knowledge base and average takes a list and returns the result but when i pose the query
"average([],X)."
it returns X=0 then when i press ; it gives me zero divisor error and I dont understand why,I tried posing the following 4 facts in the KB
average(0,0).
average([],0).
average(0/0,0).
average(0,0/0).
I'm not sure what you trying to achieve by writing 0/0 (as a matter of fact I'm not sure what any of the facts other than average([],0). are there for), but clearly dividing 0 by 0 will cause a division by zero error.
So that's your problem. Remove the occurrences of 0/0 and the error will disappear.
what is the code of average/2?
assuming that the current code is:
average(L,X):-
sumlist(L,Sum),
length(L,N),
X is Sum/N.
then you should enter the special case like this:
average([],0).
average(L,X):-
sumlist(L,Sum),
length(L,N),
X is Sum/N.
this will have the behavior you described: "when I try posing the query average([],X). it returns X=0 which is true but I can still press ; which gives a 0/0 division error .. "
to avoid the second error you should prevent prolog from continuing to the second clause if the list is empty.
you can do that either with a cut:
average([],0):-!.
average(L,X):-
sumlist(L,Sum),
length(L,N),
X is Sum/N.
or by checking the length of the list before dividing
average([],0):-!.
average(L,X):-
sumlist(L,Sum),
length(L,N),
N>0,
X is Sum/N.
I can't comment on thanosQR's answer (insufficient rep) but you can avoid the cuts by pattern matching:
average([], 0).
average([H|T], X):-
sumlist([H|T], Sum),
length([H|T], N),
X is Sum / N.
or using the if -> then ; else construct:
average(L, X):-
( L = [] ->
X = 0
; sumlist(L, Sum),
length(L, N),
X is Sum / N
).

Prolog, using expressions

I'm trying to learn SWI prolog,
but my simple program fails when I believe it should succeed.
%My code:
orthogonal((X1,Y1,Z1),(X2,Y2,Z2)) :- (X1*X2)+(Y1*Y2)+(Z1*Z2)==0.
integerVector((X,Y,Z)) :- integer(X),integer(Y),integer(Z).
?-orthogonal((1,0,0),(0,0,1)).
I press compile Buffer in the pseudoemacs window and the output is:
% [PATH].pl compiled 0.00 sec, 136 bytes
ERROR: emacs_prolog_mode ->error_at_location: Argument 1 (int): `int' expected, found `#11470948?start'
ERROR: emacs_prolog_mode ->error_at_location: Argument 1 (int): `int' expected, found `#11470948?start'
Warning: [PATH]s.pl:5:
Goal (directive) failed: user:orthogonal((1,0,0), (0,0,1))
You have used (==)/2 in place of (=:=)/2 which evaluates its arguments as arithmetic expressions.
You can use (X,Y,Z), but it isn't a triple as in e.g. Haskell. To see this:
?- write_canonical((1,2,3)).
','(1,','(2,3))
?- (1,2,3) = (X,Y).
X = 1, Y = (2,3).
Expressions in Prolog simply represent syntactic term trees. To evaluate an expression you need to X is Y which evaluates Y as an arithmetic expression and unifies the result with X. Alternatively you can use X =:= Y which evaluates both X and Y as arithmetic expressions, then unifies the results.
Cheers!

Resources