<div class="notebook"> <div class="nb-cell markdown"> # R/SWISH demos R for SWISH provides an interface to [Rserve](https://rforge.net/Rserve/) where the access predicates are inspired by [Real](http://stoics.org.uk/~nicos/sware/real/) by [Nicos Angelopoulos](http://stoics.org.uk/~nicos/). The interface defines two predicates and a [quasi quotation](http://www.swi-prolog.org/pldoc/man?section=quasiquotations): $ Var <- Expression : Evaluate _Expression_ and bind the result to _Var_. _Var_ can both be a Prolog variable, which causes the R expression to be converted into Prolog or an R variable (atom), which causes the result to be bound to an R variable. $ <- Expression : Evaluate _Expression_ and display the resulting R console output. $ {|r(Arg ...)||R-code|} : In this quasi quotation, `r` specifies the syntax. `Arg ...` is a list of Prolog terms that are translated to R and bound to an R variable with the same name. `R-code` is arbitrary R code. This may contain any characters except for the `|}` termination sequence. Above, *Expression* is either a Prolog term or a quasi quotation. If it is a Prolog term, it is translated into R using these rules: - An identifier (atom with chars valid for R identifiers) are emitted verbatim. - The Prolog atoms `true` and `false` are translated into the R expressions =TRUE= and =FALSE=. - A Prolog string is translated into an R string. Note that R strings may be written as `"string"` or `'string'`, while in Prolog `'string'` is an atom, which is treated as an identifier. Thus, use double quoted Prolog strings to create a string in R. - Numbers are translated into R numbers. - A term =|functor(Arg ...)|= is translated into an R-function call. - The R operators are supported: =|+, -, *, /, mod, '%%', ^, >=, >, ==, <, <=, =<, \=, '!=', :, <-|= - =|A$B|= and =|A[I]|= are supported - Goal expansion is provided to turn =|a.b|= and =|a.b()|= into valid syntax. </div> <div class="nb-cell markdown"> ## Exchange data between Prolog and R Data may be transferred using the assignment operator `Target <- Source`, where `Source` is the Prolog representation of an R expression. `Target` is either a Prolog variable, transferring the value of an R expression to Prolog, or an R variable or expression, transferring a Prolog expression to R. First we illustrate exchanging R data to Prolog. Note that the expression can both be the Prolog representation of an R expression or R source represented as a quasi quotation. </div> <div class="nb-cell query"> A <- 1:10. </div> <div class="nb-cell query"> A <- {|r||1:10|}. </div> <div class="nb-cell markdown"> Next, we transfer data from Prolog to R. We compute the mean and return it to show that `a <- List` actuall binds the R variable `a`. </div> <div class="nb-cell query"> numlist(0, 10, List), a <- List, Mean <- mean(a). </div> <div class="nb-cell markdown"> The left side of the assignment can be any valid R term as illustrated below, where we assign the column names of a data frame. See [Data frame](example/Rdataframe.swinb) for more high level operations on data frames. </div> <div class="nb-cell query"> df <- data.frame([100,200,300]), colnames(df) <- ["hundreds"], <- df. </div> <div class="nb-cell markdown"> ## Simple plot examples First, we make some trivial plots using an R vector, Prolog list and a _quasi quotation_. </div> <div class="nb-cell query"> <- plot(c(1,2,3)). </div> <div class="nb-cell query"> <- plot([1,2,3,4]). </div> <div class="nb-cell query"> {|r||plot(c(1,2,3))|}. </div> <div class="nb-cell query"> numlist(1, 25, Data), {|r(Data)||plot(Data)|}. </div> <div class="nb-cell markdown"> ## Performance tests for transferring data Below we compare computing the mean from a list of 1M integers through R as well as natively in Prolog. It turns out R does the job faster on a large number of integers than Prolog. Why? Once in R, the array is a simple C array of integers, causing a blindly fast addition. The Prolog counterpart adds the numbers one-by-one and does rigid overflow checking and handling. </div> <div class="nb-cell query"> numlist(1, 1 000 000, _L), time(A <- mean(_L)). </div> <div class="nb-cell query"> numlist(1, 1 000 000, _L), time(sum_list(_L, Sum)). </div> <div class="nb-cell markdown"> ## Show error handling </div> <div class="nb-cell query"> A <- {|r||a b|}. </div> <div class="nb-cell markdown"> ## Using ggplot2 to render plots The library("ggplot2") can be used for rendering plots. Unlike native plot() however, the call should be made with <-/1 because ggplot relies on console output. We first give the example using an R quasi quotation, followed by using a Prolog term. Note that - Quasi quotations can be used to copy/paste R code into your Prolog program without changing it (except when it contains =||}|=). - Prolog code may need minor modifications. In the example, =|I(.5)|= must be changed to `'I'(0.5)` because Prolog floats cannot start with a =|.|= and functors (used as function symbols) cannot start with a capital. The Prolog approach however - Is better portable. - Profits from Prolog syntax checking. - Makes it easier to compose R expressions from smaller elements. </div> <div class="nb-cell program"> :- <- library("ggplot2"). </div> <div class="nb-cell query"> <- {|r||qplot(mpg, data=mtcars, geom="density", fill=gear, alpha=I(.5), main="Distribution of Gas Milage", xlab="Miles Per Gallon", ylab="Density")|}. </div> <div class="nb-cell query"> <- qplot(mpg, data=mtcars, geom="density", fill=gear, alpha='I'(0.5), main="Distribution of Gas Milage", xlab="Miles Per Gallon", ylab="Density"). </div> <div class="nb-cell markdown"> ## Query and handle data frames This shows how to print a data frame and how to get R data into Prolog. Note that the interface merely fetches the matrix as a nested list of columns. The library(r/r_data) provides utilites for creating and fetching R data frames from Prolog. This [notebook](example/Rdataframe.swinb) illustrates the library. </div> <div class="nb-cell program" data-background="true"> :- use_rendering(table). </div> <div class="nb-cell query"> <- mtcars. </div> <div class="nb-cell query"> MtCars <- mtcars, Cols <- colnames(mtcars), Rows <- rownames(mtcars). </div> </div>