library(ctypes)
One of the problems facing anyone who uses Prolog on more than one system is that different operating systems use different characters to signal the end of a line or the end of a file. We have
Dialect DEC-10 Prolog SICStus Prolog Quintus Prolog OS (TOPS-10) (UNIX,Windows) (UNIX,Windows) end-of-line 31 (^_) 10 (LF, ^J) 10 (LF, ^J) end-of-file 26 (^Z) -1 -1
Windows note: From an application program's point of view, each line in the file is terminated with a single <LFD>. However, what's actually stored in the file is the sequence <RET><LFD>.
A prudent Prolog programmer will try to avoid writing these constants into his program. Indeed, a prudent Prolog programmer will try to avoid relying too much on the fact that Prolog uses the ASCII character set.
Quintus Prolog addresses these problems by imitating the programming language
C. The package library(ctypes)
defines predicates that recognize or
enumerate certain types of characters. Where possible, the names and
the character sets
have been borrowed from C.
Except as indicated, all of the predicates in library(ctypes)
check the
type of a given character,
or backtrack over all the characters of the appropriate type if
given a variable.
is_endfile(
-Char)
get0/1
returns it,
the end of the input file has been reached, and the file should not be
read further. No special significance is attached to this
character on output; it might not be a valid output character at all (as
in Quintus Prolog) or it might simply be written out along with other text.
The need for this predicate is largely obviated by the built-in predicate
at_end_of_file/[0,1]
in Release 3.
is_newline(
-Char)
get0/1
at the end of an input line.
The end-of-line character is a valid output character, and when
written to a file ends the current output line. It should not be used to
start lines, only to end them.
The need for this predicate is largely obviated by the built-in predicate
skip_line/[0,1]
in Release 3.
is_newpage(
-Char)
get0/1
at the end of an input page. It is a valid output
character,
and when written to a file ends the current output page. It should not be
used to start pages, only to end them.
is_endline(
+Char)
stty(1)
command.
is_endline/1
accepts most ASCII control characters, but not space, tab,
or delete, which covers all the line terminators likely to arise in
practice. It should only be used to recognize line terminators; if
passed a variable, it will raise an error exception.
The need for this predicate is largely obviated by the built-in predicate
at_end_of_line/[0,1]
in Release 3.
is_alnum(
?Char)
_
is
not an alphanumeric character. (See is_csym/1
below.)
is_alpha(
?Char)
_
is not
a letter. (See is_csymf/1
below.)
is_ascii(
?Char)
is_ascii/1
(like most of the predicates in this section) will try to bind it to
each of the acceptable values in turn (that is, it will enumerate them).
Whether the end-of-file character satisfies is_ascii/1
or not is
system-dependent.
is_char(?Char)
is_cntrl(
?Char)
is_csym(
?Char)
$
. In such a system, C's version of iscsym/1
will accept those
additional characters, but Prolog's will not.
is_csymf(
?Char)
is_digit(
?Char)
is_digit(
?Char,
?Weight)
is_digit(
?Char,
?Base,
?Weight)
is_digit(97 /* a */, 16, 10) is_digit(52 /* 4 */, 10, 4) is_digit(70 /* F */, 16, 15)
This is a genuine relation; it may be used all possible ways. You can
even use it to enumerate all the triples that satisfy the relation. Each
argument must be either a variable or an integer.
is_graph(
?Char)
! " # $ % & ' ( ) * ; < = > ? @ [ \ ] ^ _ ` { | } ~ + , - . / :
is_lower(
+Char)
is_paren(
?Left,
?Right)
(
and )
, [
and ]
, or {
and }
.
is_period(
?Char)
is_period/1
recognizes each of the three punctuation marks that
can end an English sentence. That is, is_period(
Char)
is true when
Char is an exclamation point (!
), a question mark (?
), or a
period (.
). Note that if you want to test specifically for a period
character, you should use the goal
Char is "."
is_print(
?Char)
is_punct(
?Char)
is_graph/1
. Note that underscore is a "punct" and so is the space character.
The reason for this is that C defines it that way, and this package
eschews innovation for innovation's sake.
is_quote(
?Char)
`
(back-quote), '
(single-quote), or "
(double-quote).
is_space(
?Char)
is_space/1
also accepts
the (31, ^_) character.
is_upper(
?Char)
is_white(
?Char)
is_space/1
is that if you skip over characters satisfying
is_space/1
you will also be skipping over the ends of lines and pages
(though at least you will not run off the end of the file), while if you
skip over characters satisfying is_white/1
you will stop at the
end of the current line.
to_lower(
?Char,
?Lower)
maplist(to_lower, X, LowerCasedX)
In normal use of to_lower/2
, Char is bound. If Char is
uninstantiated, to_lower/2
will still work correctly, but will be less efficient. If you
want to convert a lowercase letter Kl to its uppercase version Ku,
do not use to_lower/2
; to_lower(Ku, 97)
has two solutions:
65 (A) and 97 (a). Use to_upper/2
instead.
to_upper(
?Char,
?Upper)
maplist(X, to_upper, UpperCasedX)
The System V macro isxdigit()
is not represented in this package because
isdigit/3
subsumes it. The System V macros _tolower()
and _toupper()
are
not represented because to_lower/2
and to_upper/2
subsume them.
The predicates needed for portability between operating systems are
is_endfile/1
is_endline/1
is_newline/1
is_newpage/1
Remember: is_endfile/1
and is_endline/1
are for recognizing the end of an
input file or the end of an input line, while is_newline/1
and is_newpage/1
return the character that you should
give to put/1
to end a line or page of output.