## ----include=FALSE------------------------------------------------------------
knitr::opts_chunk$set(collapse=TRUE, comment="#>")
library(htmltools)

## -----------------------------------------------------------------------------
library(rolog)

## -----------------------------------------------------------------------------
# member(1, [1, 2.0, a, "b", X, true])
query(call("member", 1L, list(1L, 2.0, quote(a), "b", expression(X), TRUE)))

# returns an empty list, stating that member(1, [1 | _]) is satisfied
submit()

# returns a list with constraints, stating that the query is also satisfied 
# if the fifth element of the list, X, is 1
submit()

# close the query
clear()

## -----------------------------------------------------------------------------
Q <- call("=", expression(X), c(1, 2, NA, NaN, Inf))
once(Q, options=list(portray=TRUE))

Q <- call("r_eval", c(1, 2, NA, NaN, Inf), expression(X))
once(Q)

## -----------------------------------------------------------------------------
options(rolog.intvec="iv")
Q <- call("member", expression(X), list(c(1L, 2L), c(3.5, 4.5)))
query(Q, options=list(realvec="rv"))
submit()
clear()

## -----------------------------------------------------------------------------
Q <- call("membr", expression(X), list(1, 2, 3))
query(Q)
try(submit())
clear()

## ----echo=FALSE, fig.width=6, fig.height=2------------------------------------
HTML('
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
 -->
<!-- Title: G Pages: 1 -->
<svg width="524pt" height="140pt"
 viewBox="0.00 0.00 523.62 140.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 136)">
<title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-136 519.6214,-136 519.6214,4 -4,4"/>
<g id="clust1" class="cluster">
<title>cluster_0</title>
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="113.7627,-72 113.7627,-124 411.314,-124 411.314,-72 113.7627,-72"/>
</g>
<g id="clust2" class="cluster">
<title>cluster_1</title>
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="111.0327,-8 111.0327,-60 414.044,-60 414.044,-8 111.0327,-8"/>
</g>
<!-- Query -->
<g id="node1" class="node">
<title>Query</title>
<polygon fill="none" stroke="#000000" points="41.5163,-125 -.0164,-100 41.5163,-75 83.049,-100 41.5163,-125"/>
<polyline fill="none" stroke="#000000" points="10.2648,-106.1886 10.2648,-93.8114 "/>
<polyline fill="none" stroke="#000000" points="31.2352,-81.1886 51.7975,-81.1886 "/>
<polyline fill="none" stroke="#000000" points="72.7679,-93.8114 72.7679,-106.1886 "/>
<polyline fill="none" stroke="#000000" points="51.7975,-118.8114 31.2352,-118.8114 "/>
<text text-anchor="middle" x="41.5163" y="-95.8" font-family="Times,serif" font-size="14.00" fill="#000000">Query</text>
</g>
<!-- r2rolog -->
<g id="node3" class="node">
<title>r2rolog</title>
<polygon fill="#ffffff" stroke="#ffffff" points="180.3888,-116 121.887,-116 121.887,-80 180.3888,-80 180.3888,-116"/>
<text text-anchor="middle" x="151.1379" y="-93.8" font-family="Times,serif" font-size="14.00" fill="#000000">preproc</text>
</g>
<!-- Query&#45;&gt;r2rolog -->
<g id="edge5" class="edge">
<title>Query&#45;&gt;r2rolog</title>
<path fill="none" stroke="#000000" d="M82.0239,-99.261C91.6985,-99.0844 102.0124,-98.8963 111.6407,-98.7206"/>
<polygon fill="#000000" stroke="#000000" points="111.8224,-102.218 121.7568,-98.536 111.6946,-95.2191 111.8224,-102.218"/>
</g>
<!-- Result -->
<g id="node2" class="node">
<title>Result</title>
<polygon fill="none" stroke="#000000" points="67.2938,-56.7775 15.7389,-56.7775 15.7389,-5.2225 67.2938,-5.2225 67.2938,-56.7775"/>
<polyline fill="none" stroke="#000000" points="27.7389,-56.7775 15.7389,-44.7775 "/>
<polyline fill="none" stroke="#000000" points="15.7389,-17.2225 27.7389,-5.2225 "/>
<polyline fill="none" stroke="#000000" points="55.2938,-5.2225 67.2938,-17.2225 "/>
<polyline fill="none" stroke="#000000" points="67.2938,-44.7775 55.2938,-56.7775 "/>
<text text-anchor="middle" x="41.5163" y="-26.8" font-family="Times,serif" font-size="14.00" fill="#000000">Result</text>
</g>
<!-- rolog2r -->
<g id="node6" class="node">
<title>rolog2r</title>
<polygon fill="#ffffff" stroke="#ffffff" points="183.3486,-52 118.9271,-52 118.9271,-16 183.3486,-16 183.3486,-52"/>
<text text-anchor="middle" x="151.1379" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">postproc</text>
</g>
<!-- Result&#45;&gt;rolog2r -->
<g id="edge8" class="edge">
<title>Result&#45;&gt;rolog2r</title>
<path fill="none" stroke="#000000" d="M77.6825,-31.9898C90.9116,-32.3518 105.7858,-32.7589 118.6719,-33.1115"/>
<polygon fill="#000000" stroke="#000000" points="77.5872,-28.4859 67.4951,-31.711 77.3956,-35.4833 77.5872,-28.4859"/>
</g>
<!-- forth -->
<g id="node4" class="node">
<title>forth</title>
<ellipse fill="#ffffff" stroke="#ffffff" cx="257.0931" cy="-98" rx="37.7006" ry="18"/>
<text text-anchor="middle" x="257.0931" y="-93.8" font-family="Times,serif" font-size="14.00" fill="#000000">(rolog)</text>
</g>
<!-- r2rolog&#45;&gt;forth -->
<g id="edge1" class="edge">
<title>r2rolog&#45;&gt;forth</title>
<path fill="none" stroke="#000000" d="M180.6523,-98C189.3761,-98 199.1636,-98 208.7474,-98"/>
<polygon fill="#000000" stroke="#000000" points="209.0069,-101.5001 219.0069,-98 209.0068,-94.5001 209.0069,-101.5001"/>
</g>
<!-- rolog_pl -->
<g id="node5" class="node">
<title>rolog_pl</title>
<polygon fill="#ffffff" stroke="#ffffff" points="403.1355,-116 333.8516,-116 333.8516,-80 403.1355,-80 403.1355,-116"/>
<text text-anchor="middle" x="368.4935" y="-93.8" font-family="Times,serif" font-size="14.00" fill="#000000">preproc/2</text>
</g>
<!-- forth&#45;&gt;rolog_pl -->
<g id="edge2" class="edge">
<title>forth&#45;&gt;rolog_pl</title>
<path fill="none" stroke="#000000" d="M295.1192,-98C304.2843,-98 314.1616,-98 323.6074,-98"/>
<polygon fill="#000000" stroke="#000000" points="323.6337,-101.5001 333.6337,-98 323.6336,-94.5001 323.6337,-101.5001"/>
</g>
<!-- Prolog -->
<g id="node9" class="node">
<title>Prolog</title>
<ellipse fill="none" stroke="#000000" cx="478.8327" cy="-66" rx="36.5786" ry="36.5786"/>
<polyline fill="none" stroke="#000000" points="503.1648,-93.5915 454.5007,-93.5915 "/>
<polyline fill="none" stroke="#000000" points="503.1648,-38.4085 454.5007,-38.4085 "/>
<text text-anchor="middle" x="478.8327" y="-61.8" font-family="Times,serif" font-size="14.00" fill="#000000">Prolog</text>
</g>
<!-- rolog_pl&#45;&gt;Prolog -->
<g id="edge6" class="edge">
<title>rolog_pl:e&#45;&gt;Prolog</title>
<path fill="none" stroke="#000000" d="M403.4935,-98C415.254,-98 427.2841,-94.6558 438.1805,-90.1297"/>
<polygon fill="#000000" stroke="#000000" points="439.7892,-93.2427 447.429,-85.9022 436.8791,-86.8763 439.7892,-93.2427"/>
</g>
<!-- back -->
<g id="node7" class="node">
<title>back</title>
<ellipse fill="#ffffff" stroke="#ffffff" cx="257.0931" cy="-34" rx="37.7006" ry="18"/>
<text text-anchor="middle" x="257.0931" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">(rolog)</text>
</g>
<!-- rolog2r&#45;&gt;back -->
<g id="edge3" class="edge">
<title>rolog2r&#45;&gt;back</title>
<path fill="none" stroke="#000000" d="M193.519,-34C201.9303,-34 210.7131,-34 218.9718,-34"/>
<polygon fill="#000000" stroke="#000000" points="193.5037,-30.5001 183.5037,-34 193.5036,-37.5001 193.5037,-30.5001"/>
</g>
<!-- pl_rolog -->
<g id="node8" class="node">
<title>pl_rolog</title>
<polygon fill="#ffffff" stroke="#ffffff" points="406.0946,-52 330.8925,-52 330.8925,-16 406.0946,-16 406.0946,-52"/>
<text text-anchor="middle" x="368.4935" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">postproc/2</text>
</g>
<!-- back&#45;&gt;pl_rolog -->
<g id="edge4" class="edge">
<title>back&#45;&gt;pl_rolog</title>
<path fill="none" stroke="#000000" d="M305.2928,-34C313.7738,-34 322.4911,-34 330.6388,-34"/>
<polygon fill="#000000" stroke="#000000" points="305.1193,-30.5001 295.1192,-34 305.1192,-37.5001 305.1193,-30.5001"/>
</g>
<!-- pl_rolog&#45;&gt;Prolog -->
<g id="edge7" class="edge">
<title>pl_rolog:e&#45;&gt;Prolog</title>
<path fill="none" stroke="#000000" d="M416.6536,-34.8303C427.7021,-36.5766 438.5788,-40.8717 448.0695,-45.7339"/>
<polygon fill="#000000" stroke="#000000" points="416.7454,-31.3262 406.4935,-34 416.1752,-38.303 416.7454,-31.3262"/>
</g>
</g>
</svg>')

## -----------------------------------------------------------------------------
a <- 5
Q <- quote(member(.X, ""[1, 2, 3, a, (a), 1 <= 2]))
once(Q, options=list(preproc=list(as.rolog, preproc), portray=TRUE))

## -----------------------------------------------------------------------------
stringify <- function(x)
{
  if(is.symbol(x))
    return(as.character(x))

  if(is.call(x))
    x[-1] <- lapply(x[-1], FUN=stringify)

  if(is.list(x))
    x <- lapply(x, FUN=stringify)

  if(is.function(x))
    body(x) <- stringify(body(x))

  return(x)
}

Q <- quote(member(.X, ""[a, b, c]))
R <- findall(Q, options=list(preproc=list(as.rolog, preproc), 
       postproc=list(stringify, postproc)))
unlist(R)

## -----------------------------------------------------------------------------
library(rolog)
consult(system.file(file.path("pl", "family.pl"), package="rolog"))
query(call("ancestor", expression(X), quote(jim)))
submit()        # solutions for X
submit()        # etc.
clear()         # close the query

## -----------------------------------------------------------------------------
consult(system.file(file.path("pl", "backdoor.pl"), package="rolog"))

node <- function(N) invisible(once(call("assert", call("node", N))))
node("a"); node("b"); node("c"); node("f"); node("u")
node("e") # exposure
node("d") # outcome

arrow <- function(X, Y) invisible(once(call("assert", call("arrow", X, Y))))
arrow("a", "d"); arrow("a", "f"); arrow("b", "d"); arrow("b", "f")
arrow("c", "d"); arrow("c", "f"); arrow("e", "d"); arrow("f", "e")
arrow("u", "a"); arrow("u", "b"); arrow("u", "c")

R <- findall(call("minimal", "e", "d", expression(S)))
unlist(R)

## -----------------------------------------------------------------------------
consult(system.file(file.path("pl", "telescope.pl"), package="rolog"))
Q <- quote(sentence(.Tree, "john sees a man with a telescope"))
unlist(findall(Q, options=list(preproc=as.rolog)))

## -----------------------------------------------------------------------------
consult(system.file(file.path("pl", "buggy.pl"), package="rolog"))
Q <- quote(search(tratio(x, mu, s, n), .S))
unlist(findall(Q, options=list(preproc=as.rolog)))

## -----------------------------------------------------------------------------
library(rolog)
consult(system.file(file.path("pl", "mathml.pl"), package="rolog"))

# R interface to Prolog predicate r2mathml/2
mathml <- function(term)
{
  t <- once(call("r2mathml", term, expression(X)))
  cat(paste(t$X, collapse=""))
}

## ----results="asis"-----------------------------------------------------------
term <- quote(pbinom(k, N, p))

# Pretty print
mathml(term)

# Do some calculations with the same term
k <- 10
N <- 22
p <- 0.4
eval(term)

## ----results="asis"-----------------------------------------------------------
term <- quote(integrate(sin, 0L, 2L*pi))
mathml(term)
eval(term)

## ----results='asis'-----------------------------------------------------------
canonical <- function(term)
{
  if(is.call(term))
  {
    f <- match.fun(term[[1]])
    if(!is.primitive(f))
      term <- match.call(f, term)
    
    # Recurse into arguments
    term[-1] <- lapply(term[-1], canonical)
  }

  return(term)
}

g <- function(u)
  sin(u)

# Mixture of (partially) named and positional arguments in unusual order
term <- quote(2L * integrate(low=-Inf, up=Inf, g)$value)
mathml(canonical(term))

# It is a bit of a mystery that R knows the result of this integral.
eval(term)

## -----------------------------------------------------------------------------
print(g)

## -----------------------------------------------------------------------------
consult(system.file(file.path("pl", "r_eval.pl"), package="rolog"))
invisible(once(call("r_seed", 123L)))
once(call("r_norm", 3L, expression(X)))

## -----------------------------------------------------------------------------
# Set variable in R, read in Prolog
env <- new.env()
with(env, a <- 1)
once(call("r_eval", quote(a), expression(X)), env=env)

# Set R variable in Prolog, read in R
invisible(once(call("r_eval", call("<-", quote(b), 2))))
cat("b =", b)

## -----------------------------------------------------------------------------
try(once(quote(r_eval(rnorm(-1))))) # return "-1" random normals

## -----------------------------------------------------------------------------
consult(system.file(file.path("pl", "interval.pl"), package="rolog"))

Q <- quote(int(`...`(1, 2) / `...`(-3, 3), .Res))
unlist(findall(Q, options=list(preproc=as.rolog)))

D  <- quote(`...`(5.7, 5.8))
mu <- 4
s  <- quote(`...`(3.8, 3.9))
N  <- 24L
tratio <- call("/", call("-", D, mu), call("/", s, call("sqrt", N)))
once(call("int", tratio, expression(Res)))

# Binomial density
prob = quote(`...`(0.2, 0.3))
once(call("int", call("dbinom", 4L, 10L, prob, FALSE), expression(Res)))

