docsc
This commit is contained in:
@@ -1,10 +1,228 @@
|
||||
The R Prolog Progrmming Interface (#real)
|
||||
===================================
|
||||
|
||||
Real
|
||||
---
|
||||
@file real.pl
|
||||
@author Nicos Angelopoulos
|
||||
@author Vitor Santos Costa
|
||||
@version 1:0:4, 2013/12/25, sinter_class
|
||||
@license Perl Artistic License
|
||||
@defgroup libReal An interface to the R statistical software.
|
||||
@ingroup packages
|
||||
|
||||
Real is a c-based interface for connecting R to Prolog.
|
||||
|
||||
YAP introduces a development version of real, developed to experiment
|
||||
This library enables the communication with an R process started as a shared library.
|
||||
It is the result of the efforts of two research groups that have worked in parallel.
|
||||
The syntactic emphasis on a minimalistic interface.
|
||||
|
||||
In the doc/ directory of the distribution there is user's guide, a published paper
|
||||
and html documentation from PlDoc (doc/html/real.html). There is large number
|
||||
of examples in `examples/for_real.pl`.
|
||||
|
||||
A single predicate (<-/2,<-/1) channels
|
||||
the bulk of the interactions. In addition to using R as a shared library, real uses
|
||||
the c-interfaces of SWI/Yap and R to pass objects in both directions.
|
||||
The usual mode of operation is to load Prolog values on to R variables and then call
|
||||
R functions on these values. The return value of the called function can be either placed
|
||||
on R variable or passed back to Prolog. It has been tested extensively on current
|
||||
SWI and YAP on Linux machines but it should also compile and work on MS operating systems and Macs.
|
||||
|
||||
The main modes for utilising the interface are
|
||||
~~~~
|
||||
<- +Rexpr
|
||||
<- +Rvar
|
||||
~~~~
|
||||
|
||||
Print Rvar or evaluate expression Rexpr in R
|
||||
~~~~
|
||||
+Rvar <- +PLdata
|
||||
+Rexpr <- +PLdata
|
||||
-PLvar <- +Rvar
|
||||
-PLvar <- +Rexpr
|
||||
+Rexpr1 <- +Rexpr2
|
||||
~~~~
|
||||
|
||||
Pass Prolog data to R, pass R data to Prolog or assign an R expression to
|
||||
an assignable R expression.
|
||||
|
||||
@defgroup TestingR Testing Real
|
||||
|
||||
There is a raft of examples packed in a singl```e file that test the library.
|
||||
|
||||
~~~~
|
||||
?- [pack(real/examples/for_real)].
|
||||
|
||||
?- for_real.
|
||||
|
||||
?- edit( pack(real/examples/for_real) ).
|
||||
~~~~
|
||||
|
||||
@defgroup RSyntax Prolog and R Syntax
|
||||
|
||||
There are syntactic conventions in R that make unparsable prolog code.
|
||||
Notably function and variable names are allowed to contain dots, square brackets are used
|
||||
to access parts of vectors and arrays and functions are allowed empty argument tuples.
|
||||
We have introduced relevant syntax which allows for easy transition between prolog and R.
|
||||
Prolog constructs are converted by the library as follows:
|
||||
|
||||
|
||||
* =|..|= within atoms -> =|.|= (ex. =| as..integer(c(1,2,3)) -> as.integer(c(1,2,3))|= )
|
||||
* =|^[]|= after atoms -> =|[]|= (ex. =|a^[2] -> a[2] |=)
|
||||
* =|(.)|= at the end of atoms that are known R functions -> =|()|= (ex. =|dev..off(.) -> dev.off()|= )
|
||||
* =|[]|= -> c() (which equal to R's NULL value)
|
||||
* ( f(x) :- (..)) -> f(x) (...)
|
||||
* Lists of lists are converted to matrices. All first level lists must have the same length.
|
||||
* Filenames must be given as Prolog strings.
|
||||
* R specific operators (eg. %*% should be quoted in Prolog.
|
||||
* + prepends strings, for (Prolog) atoms: +'String'
|
||||
* Expressions that pose difficulty in translation can always be passed as unquoted Prolog atoms or strings.
|
||||
]]* since 0:1:2 foo() is valid syntax: =|<- dev..off() |= works now (with no need for dev..off(.))
|
||||
* since 0:1:2 mat[1] is valid syntax: =|m[1] <- 4|= works now (with no need for m^[...])
|
||||
|
||||
@defgroup RDataTransfer Mapping Data betweenn Prolog and R
|
||||
|
||||
R vectors are mapped to prolog lists and matrices are mapped to nested lists.
|
||||
The convention works the other way around too.
|
||||
|
||||
There are two ways to pass prolog data to R. The more efficient one is by using
|
||||
~~~~
|
||||
Rvar <- PLdata
|
||||
~~~~
|
||||
|
||||
Where Pldata is one of the basic data types (number,boolean) a list or a c/n term.
|
||||
This transfers via C data between R and Prolog. In what follows atomic PLval data
|
||||
are simply considered as singleton lists.
|
||||
Flat Pldata lists are translated to R vectors and lists of one level of nesting to R matrices
|
||||
(which are 2 dimensional arrays in R parlance). The type of values of the vector or matrice is
|
||||
taken to be the type of the first data element of the Pldata according to the following :
|
||||
|
||||
* integer -> integer
|
||||
* float -> double
|
||||
* atom -> char
|
||||
* boolean -> logical
|
||||
|
||||
Booleans are represented in prolog as true/false atoms.
|
||||
Currently arrays of aribtrary dimensions are not supported in the low-level interface.
|
||||
Note that in R a scalar is just a one element vector. When passing non-scalars the
|
||||
interface will assume the type of the object is that of the first scalar until it encounters
|
||||
something different.
|
||||
Real will currently re-start and repopulate partial integers for floats as illustrated
|
||||
below:
|
||||
|
||||
~~~~
|
||||
r <- [1,2,3]. % pass 1,2,3 to an R vector r
|
||||
R <- r. % pass contents of R vector r to Prolog variable R
|
||||
R = [1, 2, 3].
|
||||
|
||||
i <- [1,2,3.1]. % r is now a vector of floats, rather than integers
|
||||
I <- i.
|
||||
I = [1.0, 2.0, 3.1].
|
||||
|
||||
|
||||
~~~~
|
||||
|
||||
However, not all possible "corrections" are currently supported. For instance,
|
||||
|
||||
~~~~
|
||||
?- c <- [a,b,c,1].
|
||||
ERROR: real:set_R_variable/2: Type error: `boolean' expected, found `a'
|
||||
~~~~
|
||||
|
||||
In the data passing mode we map Prolog atoms to R strings-
|
||||
|
||||
~~~~
|
||||
?- x <- [abc,def].
|
||||
true.
|
||||
|
||||
?- <- x.
|
||||
[1] "abc" "def"
|
||||
true.
|
||||
|
||||
?- X <- x.
|
||||
X = [abc, def].
|
||||
|
||||
~~~~
|
||||
|
||||
In addition, Prolog data can be passed through the expression mechanism.
|
||||
That is, data appearing in an arbitrary R expression will be parsed and be part of the long
|
||||
string that will be passed from Prolog to R for evaluation.
|
||||
This is only advisable for short data structures. For instance,
|
||||
|
||||
~~~~
|
||||
tut_4a :-
|
||||
state <- c(+"tas", +"sa", +"qld", +"nsw", +"nsw"),
|
||||
<- state.
|
||||
|
||||
tut_4b :-
|
||||
state <- c(+tas, +sa, +qld, +nsw, +nsw),
|
||||
<- state.
|
||||
~~~~
|
||||
|
||||
Through this interface it is more convenient to be explicit about R chars by Prolog prepending
|
||||
atoms or codes with + as in the above example.
|
||||
|
||||
@defgroup RealExamples Examples
|
||||
|
||||
~~~~
|
||||
|
||||
?- e <- numeric(.).
|
||||
yes
|
||||
?- e^[3] <- 17.
|
||||
yes
|
||||
?- e[3] <- 17.
|
||||
yes
|
||||
?- Z <- e.
|
||||
Z = ['$NaN','$NaN',17.0]
|
||||
?- e^[10] <- 12.
|
||||
yes
|
||||
?- Z <- e.
|
||||
Z = ['$NaN','$NaN',17.0,'$NaN','$NaN','$NaN','$NaN','$NaN','$NaN',12.0]
|
||||
|
||||
rtest :-
|
||||
y <- rnorm(50), % get 50 random samples from normal distribution
|
||||
<- y, % print the values via R
|
||||
x <- rnorm(y), % get an equal number of normal samples
|
||||
<- x11(width=5,height=3.5), % create a plotting window
|
||||
<- plot(x,y) % plot the two samples
|
||||
r_wait, % wait for user to hit Enter
|
||||
% <- dev..off(.). % old syntax, still supported
|
||||
<- dev.off(). % close the plotting window. foo() now acceptable in supported Prologs
|
||||
|
||||
tut6 :-
|
||||
d <- outer(0:9, 0:9),
|
||||
fr <- table(outer(d, d, "-")),
|
||||
<- plot(as..numeric(names(fr)), fr, type="h", xlab="Determinant", ylab="Frequency").
|
||||
|
||||
tut4b :-
|
||||
state <- [tas,sa,qld,nsw,nsw,nt,wa],
|
||||
statef <- factor(state),
|
||||
incmeans <- tapply( c(60, 49, 40, 61, 64, 60, 59), statef, mean ),
|
||||
<- incmeans.
|
||||
|
||||
logical :-
|
||||
t <- [1,2,3,4,5,1],
|
||||
s <- t~~~~1,
|
||||
<- s,
|
||||
S <- s,
|
||||
write( s(S) ), nl.
|
||||
|
||||
~~~~
|
||||
|
||||
#### Info
|
||||
|
||||
@see http://stoics.org.uk/~nicos/sware/real
|
||||
@see pack(real/examples/for_real)
|
||||
@see pack(real/doc/real.html)
|
||||
@see pack(real/doc/guide.pdf)
|
||||
@see pack(real/doc/padl2013-real.pdf)
|
||||
@see http://www.r-project.org/
|
||||
|
||||
Also @subpaage yap-real describes the YAP specfic details in real.
|
||||
|
||||
*/Development of real in YAP (#yap-real)
|
||||
---------------------------
|
||||
|
||||
|
||||
YAP includes a development version of real, designed to experiment
|
||||
with the internals of the implementation of R. It includes major
|
||||
changes and is likely to be much less stable than the version
|
||||
maintained by Nicos ANgelopoulos. We refer to the version herein as
|
||||
@@ -56,4 +274,3 @@ March, 2014
|
||||
|
||||
Updates: Vitor Santos Costa
|
||||
Dec. 2015
|
||||
|
||||
|
@@ -10,15 +10,6 @@
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
/**
|
||||
|
||||
@file real.pl
|
||||
@author Nicos Angelopoulos
|
||||
@author Vitor Santos Costa
|
||||
@version 1:0:4, 2013/12/25, sinter_class
|
||||
@license Perl Artistic License
|
||||
|
||||
*/
|
||||
|
||||
:- module(real, [
|
||||
start_r/0,
|
||||
@@ -76,220 +67,6 @@
|
||||
%:- set_prolog_flag(double_quotes, string ).
|
||||
|
||||
|
||||
/** @defgroup libReal An interface to the R statistical software.
|
||||
@ingroup packages
|
||||
|
||||
#### Introduction
|
||||
|
||||
This library enables the communication with an R process started as a shared library.
|
||||
It is the result of the efforts of two research groups that have worked in parallel.
|
||||
The syntactic emphasis on a minimalistic interface.
|
||||
|
||||
In the doc/ directory of the distribution there is user's guide, a published paper
|
||||
and html documentation from PlDoc (doc/html/real.html). There is large number
|
||||
of examples in `examples/for_real.pl`.
|
||||
|
||||
A single predicate (<-/2,<-/1) channels
|
||||
the bulk of the interactions. In addition to using R as a shared library, real uses
|
||||
the c-interfaces of SWI/Yap and R to pass objects in both directions.
|
||||
The usual mode of operation is to load Prolog values on to R variables and then call
|
||||
R functions on these values. The return value of the called function can be either placed
|
||||
on R variable or passed back to Prolog. It has been tested extensively on current
|
||||
SWI and YAP on Linux machines but it should also compile and work on MS operating systems and Macs.
|
||||
|
||||
The main modes for utilising the interface are
|
||||
~~~~
|
||||
<- +Rexpr
|
||||
<- +Rvar
|
||||
~~~~
|
||||
|
||||
Print Rvar or evaluate expression Rexpr in R
|
||||
~~~~
|
||||
+Rvar <- +PLdata
|
||||
+Rexpr <- +PLdata
|
||||
-PLvar <- +Rvar
|
||||
-PLvar <- +Rexpr
|
||||
+Rexpr1 <- +Rexpr2
|
||||
~~~~
|
||||
|
||||
Pass Prolog data to R, pass R data to Prolog or assign an R expression to
|
||||
an assignable R expression.
|
||||
|
||||
#### Testing
|
||||
|
||||
There is a raft of examples packed in a singl```e file that test the library.
|
||||
|
||||
~~~~
|
||||
?- [pack(real/examples/for_real)].
|
||||
|
||||
?- for_real.
|
||||
|
||||
?- edit( pack(real/examples/for_real) ).
|
||||
~~~~
|
||||
|
||||
#### Syntax
|
||||
|
||||
There are syntactic conventions in R that make unparsable prolog code.
|
||||
Notably function and variable names are allowed to contain dots, square brackets are used
|
||||
to access parts of vectors and arrays and functions are allowed empty argument tuples.
|
||||
We have introduced relevant syntax which allows for easy transition between prolog and R.
|
||||
Prolog constructs are converted by the library as follows:
|
||||
|
||||
|
||||
* =|..|= within atoms -> =|.|= (ex. =| as..integer(c(1,2,3)) -> as.integer(c(1,2,3))|= )
|
||||
* =|^[]|= after atoms -> =|[]|= (ex. =|a^[2] -> a[2] |=)
|
||||
* =|(.)|= at the end of atoms that are known R functions -> =|()|= (ex. =|dev..off(.) -> dev.off()|= )
|
||||
* =|[]|= -> c() (which equal to R's NULL value)
|
||||
* ( f(x) :- (..)) -> f(x) (...)
|
||||
* Lists of lists are converted to matrices. All first level lists must have the same length.
|
||||
* Filenames must be given as Prolog strings.
|
||||
* R specific operators (eg. %*% should be quoted in Prolog.
|
||||
* + prepends strings, for (Prolog) atoms: +'String'
|
||||
* Expressions that pose difficulty in translation can always be passed as unquoted Prolog atoms or strings.
|
||||
]]* since 0:1:2 foo() is valid syntax: =|<- dev..off() |= works now (with no need for dev..off(.))
|
||||
* since 0:1:2 mat[1] is valid syntax: =|m[1] <- 4|= works now (with no need for m^[...])
|
||||
|
||||
|
||||
#### Data transfers
|
||||
|
||||
R vectors are mapped to prolog lists and matrices are mapped to nested lists.
|
||||
The convention works the other way around too.
|
||||
|
||||
There are two ways to pass prolog data to R. The more efficient one is by using
|
||||
~~~~
|
||||
Rvar <- PLdata
|
||||
~~~~
|
||||
|
||||
Where Pldata is one of the basic data types (number,boolean) a list or a c/n term.
|
||||
This transfers via C data between R and Prolog. In what follows atomic PLval data
|
||||
are simply considered as singleton lists.
|
||||
Flat Pldata lists are translated to R vectors and lists of one level of nesting to R matrices
|
||||
(which are 2 dimensional arrays in R parlance). The type of values of the vector or matrice is
|
||||
taken to be the type of the first data element of the Pldata according to the following :
|
||||
|
||||
* integer -> integer
|
||||
* float -> double
|
||||
* atom -> char
|
||||
* boolean -> logical
|
||||
|
||||
Booleans are represented in prolog as true/false atoms.
|
||||
Currently arrays of aribtrary dimensions are not supported in the low-level interface.
|
||||
Note that in R a scalar is just a one element vector. When passing non-scalars the
|
||||
interface will assume the type of the object is that of the first scalar until it encounters
|
||||
something different.
|
||||
Real will currently re-start and repopulate partial integers for floats as illustrated
|
||||
below:
|
||||
|
||||
~~~~
|
||||
r <- [1,2,3]. % pass 1,2,3 to an R vector r
|
||||
R <- r. % pass contents of R vector r to Prolog variable R
|
||||
R = [1, 2, 3].
|
||||
|
||||
i <- [1,2,3.1]. % r is now a vector of floats, rather than integers
|
||||
I <- i.
|
||||
I = [1.0, 2.0, 3.1].
|
||||
|
||||
|
||||
~~~~
|
||||
|
||||
However, not all possible "corrections" are currently supported. For instance,
|
||||
|
||||
~~~~
|
||||
?- c <- [a,b,c,1].
|
||||
ERROR: real:set_R_variable/2: Type error: `boolean' expected, found `a'
|
||||
~~~~
|
||||
|
||||
In the data passing mode we map Prolog atoms to R strings-
|
||||
|
||||
~~~~
|
||||
?- x <- [abc,def].
|
||||
true.
|
||||
|
||||
?- <- x.
|
||||
[1] "abc" "def"
|
||||
true.
|
||||
|
||||
?- X <- x.
|
||||
X = [abc, def].
|
||||
|
||||
~~~~
|
||||
|
||||
In addition, Prolog data can be passed through the expression mechanism.
|
||||
That is, data appearing in an arbitrary R expression will be parsed and be part of the long
|
||||
string that will be passed from Prolog to R for evaluation.
|
||||
This is only advisable for short data structures. For instance,
|
||||
|
||||
~~~~
|
||||
tut_4a :-
|
||||
state <- c(+"tas", +"sa", +"qld", +"nsw", +"nsw"),
|
||||
<- state.
|
||||
|
||||
tut_4b :-
|
||||
state <- c(+tas, +sa, +qld, +nsw, +nsw),
|
||||
<- state.
|
||||
~~~~
|
||||
|
||||
Through this interface it is more convenient to be explicit about R chars by Prolog prepending
|
||||
atoms or codes with + as in the above example.
|
||||
|
||||
#### Examples
|
||||
|
||||
~~~~
|
||||
|
||||
?- e <- numeric(.).
|
||||
yes
|
||||
?- e^[3] <- 17.
|
||||
yes
|
||||
?- e[3] <- 17.
|
||||
yes
|
||||
?- Z <- e.
|
||||
Z = ['$NaN','$NaN',17.0]
|
||||
?- e^[10] <- 12.
|
||||
yes
|
||||
?- Z <- e.
|
||||
Z = ['$NaN','$NaN',17.0,'$NaN','$NaN','$NaN','$NaN','$NaN','$NaN',12.0]
|
||||
|
||||
rtest :-
|
||||
y <- rnorm(50), % get 50 random samples from normal distribution
|
||||
<- y, % print the values via R
|
||||
x <- rnorm(y), % get an equal number of normal samples
|
||||
<- x11(width=5,height=3.5), % create a plotting window
|
||||
<- plot(x,y) % plot the two samples
|
||||
r_wait, % wait for user to hit Enter
|
||||
% <- dev..off(.). % old syntax, still supported
|
||||
<- dev.off(). % close the plotting window. foo() now acceptable in supported Prologs
|
||||
|
||||
tut6 :-
|
||||
d <- outer(0:9, 0:9),
|
||||
fr <- table(outer(d, d, "-")),
|
||||
<- plot(as..numeric(names(fr)), fr, type="h", xlab="Determinant", ylab="Frequency").
|
||||
|
||||
tut4b :-
|
||||
state <- [tas,sa,qld,nsw,nsw,nt,wa],
|
||||
statef <- factor(state),
|
||||
incmeans <- tapply( c(60, 49, 40, 61, 64, 60, 59), statef, mean ),
|
||||
<- incmeans.
|
||||
|
||||
logical :-
|
||||
t <- [1,2,3,4,5,1],
|
||||
s <- t~~~~1,
|
||||
<- s,
|
||||
S <- s,
|
||||
write( s(S) ), nl.
|
||||
|
||||
~~~~
|
||||
|
||||
#### Info
|
||||
|
||||
@see http://stoics.org.uk/~nicos/sware/real
|
||||
@see pack(real/examples/for_real)
|
||||
@see pack(real/doc/real.html)
|
||||
@see pack(real/doc/guide.pdf)
|
||||
@see pack(real/doc/padl2013-real.pdf)
|
||||
@see http://www.r-project.org/
|
||||
|
||||
*/
|
||||
|
||||
%%%
|
||||
|
||||
init_r_env :-
|
||||
|
Reference in New Issue
Block a user