samer@2: \documentclass[10pt]{article} samer@2: \usepackage{pldoc} samer@2: \sloppy samer@2: \makeindex samer@2: samer@2: \begin{document} samer@2: % This LaTeX document was generated using the LaTeX backend of PlDoc, samer@2: % The SWI-Prolog documentation system samer@2: samer@2: samer@2: samer@2: \section{plml: Prolog-Matlab interface} samer@2: samer@2: \label{sec:plml} samer@2: samer@2: \begin{tags} samer@2: \tag{To be done} samer@2: Use mat(I) and tmp(I) as types to include engine Id. samer@2: samer@2: Clarify relationship between return values and valid Matlab denotation. samer@2: samer@2: Reshape/2 array representation: reshape([ ... ],Size) samer@2: Expression language: arr(Vals,Shape,InnerFunctor) - allows efficient samer@2: representation of arrays of arbitrary things. Will require more strict samer@2: nested list form. samer@2: samer@2: Deprecate old array(Vals::Type) and cell(Vals::Type) left-value syntax. samer@2: samer@2: Remove I from \dcgref{ml_expr}{2} and add to mx type? samer@2: \end{tags} samer@2: samer@2: \paragraph{Types} samer@2: samer@2: \textbf{ml_eng} - Any atom identifying a Matlab engine. samer@2: samer@2: \textbf{ml_stmt} - A Matlab statement samer@2: samer@2: \begin{code} samer@2: X;Y :: ml_stmt :- X:ml_stmt, Y:ml_stmt. samer@2: X,Y :: ml_stmt :- X:ml_stmt, Y:ml_stmt. samer@2: X=Y :: ml_stmt :- X:ml_lval, Y:ml_expr. samer@2: hide(X) :: ml_stmt :- X:ml_stmt. samer@2: \end{code} samer@2: samer@2: \begin{code} samer@2: ml_expr(A) % A Matlab expression, possibly with multiple return values samer@2: ml_loc ---> mat(atom,atom). % Matbase locator samer@2: \end{code} samer@2: samer@2: \paragraph{Matlab expression syntax} samer@2: samer@2: The Matlab expression syntax adopted by this module allows Prolog terms to represent samer@2: or denote Matlab expressions. Let T be the domain of recognised Prolog terms (corresponding to samer@2: the type ml_expr), and M be the domain of Matlab expressions written in Matlab syntax. samer@2: Then V : T\Sifthen{}M is the valuation function which maps Prolog term X to Matlab expression V[X]. samer@2: These are some of the constructs it recognises: samer@2: samer@2: Constructs valid only in top level statements, not subexpressions: samer@2: samer@2: \begin{code} samer@2: X;Y % |--> V[X]; V[Y] (sequential evaluation hiding first result) samer@2: X,Y % |--> V[X], V[Y] (sequential evaluation displaying first result) samer@2: X=Y % |--> V[X]=V[Y] (assignment, X must denote a valid left-value) samer@2: hide(X) % |--> V[X]; (execute X but hide return value) samer@2: \end{code} samer@2: samer@2: Things that look and work like Matlab syntax (more or less): samer@2: samer@2: \begin{code} samer@2: +X % |--> uplus(V[X]) samer@2: -X % |--> uminus(V[X]) samer@2: X+Y % |--> plus(V[X],V[Y]) samer@2: X-Y % |--> minus(V[X],V[Y]) samer@2: X^Y % |--> mpower(V[X],V[Y]) samer@2: X*Y % |--> mtimes(V[X],V[Y]) samer@2: X/Y % |--> mrdivide(V[X],V[Y]) samer@2: X\Y % |--> mldivide(V[X],V[Y]) samer@2: X.^Y % |--> power(V[X],V[Y]) samer@2: X.*Y % |--> times(V[X],V[Y]) samer@2: X./Y % |--> rdivide(V[X],V[Y]) samer@2: X.\Y % |--> ldivide(V[X],V[Y]) samer@2: X:Y:Z % |--> colon(V[X],V[Y],V[Z]) samer@2: X:Z % |--> colon(V[X],V[Z]) samer@2: X>Z % |--> gt(V[X],V[Y]) samer@2: X>=Z % |--> ge(V[X],V[Y]) samer@2: X lt(V[X],V[Y]) samer@2: X= le(V[X],V[Y]) samer@2: X==Z % |--> eq(V[X],V[Y]) samer@2: [X1,X2,...] % |--> [ V[X1], V[X2], ... ] samer@2: [X1;X2;...] % |--> [ V[X1]; V[X2]; ... ] samer@2: {X1,X2,...} % |--> { V[X1], V[X2], ... } samer@2: {X1;X2;...} % |--> { V[X1]; V[X2]; ... } samer@2: @X % |--> @V[X] (function handle) samer@2: \end{code} samer@2: samer@2: Things that do not look like Matlab syntax but provide standard Matlab features: samer@2: samer@2: \begin{code} samer@2: 'Infinity' % |--> inf (positive infinity) samer@2: 'Nan' % |--> nan (not a number) samer@2: X`` % |--> ctranpose(V[X]) (conjugate transpose, V[X]') samer@2: X#Y % |--> getfield(V[X],V[q(Y)]) samer@2: X\\Y % |--> @(V[X])V[Y] (same as lambda(X,Y)) samer@2: \\Y % |--> @()V[Y] (same as thunk(Y)) samer@2: lambda(X,Y) % |--> @(V[X])V[Y] (anonymous function with arguments X) samer@2: thunk(Y) % |--> @()V[Y] (anonymous function with no arguments) samer@2: vector(X) % |--> horzcat(V[X1],V[X2], ...) samer@2: atvector(X) % as vector but assumes elements of X are assumed all atomic samer@2: cell(X) % construct 1xN cell array from elements of X samer@2: `X % same as q(X) samer@2: q(X) % wrap V[X] in single quotes (escaping internal quotes) samer@2: qq(X) % wrap V[X] in double quotes (escaping internal double quotes) samer@2: tq(X) % wrap TeX expression in single quotes (escape internal quotes) samer@2: \end{code} samer@2: samer@2: Referencing different value representations. samer@2: samer@2: \begin{code} samer@2: mat(X,Y) % denotes a value in the Matbase using a dbload expression samer@2: mx(X:mx_blob) % denotes an MX Matlab array in SWI memory samer@2: ws(X:ws_blob) % denotes a variable in a Matlab workspace samer@2: wsseq(X:ws_blob) % workspace variable containing list as cell array. samer@2: \end{code} samer@2: samer@2: Tricky bits. samer@2: samer@2: \begin{code} samer@2: apply(X,AX) % X must denote a function or array, applied to list of arguments AX. samer@2: cref(X,Y) % cell dereference, |--> V[X]{ V[Y1], V[Y2], ... } samer@2: arr(Lists) % multidimensional array from nested lists. samer@2: arr(Lists,Dims) % multidimensional array from nested lists. samer@2: \end{code} samer@2: samer@2: Things to bypass default formatting samer@2: samer@2: \begin{code} samer@2: noeval(_) % triggers a failure when processed samer@2: atom(X) % write atom X as write/1 samer@2: term(X) % write term X as write/1 samer@2: \(P) % escape and call phrase P directly to generate Matlab string samer@2: $(X) % calls pl2ml_hook/2, denotes V[Y] where plml_hook(X,Y). samer@2: '$VAR'(N) % gets formatted as p_N where N is assumed to be atomic. samer@2: \end{code} samer@2: samer@2: All other Prolog atoms are written using \predref{write}{1}, while other Prolog terms samer@2: are assumed to be calls to Matlab functions named according to the head functor. samer@2: Thus V[ $<$head$>$( $<$arg1$>$, $<$arg2$>$, ...) ] = $<$head$>$(V[$<$arg1$>$, V[$<$arg2$>$], ...). samer@2: samer@2: There are some incompatibilities between Matlab syntax and Prolog syntax, samer@2: that is, syntactic structures that Prolog cannot parse correctly: samer@2: samer@2: \begin{itemize} samer@2: \item 'Command line' syntax, ie where a function of string arguments: samer@2: "save('x','Y')" can be written as "save x Y" in Matlab, samer@2: but in Prolog, you must use function call syntax with quoted arguments: samer@2: save(`x,`'Y'). samer@2: \item Matlab's postfix transpose operator "x'" must be written using a different samer@2: posfix operator "x``" or function call syntax "ctranspose(x)". samer@2: \item Matlab cell referencing using braces, as in x\{1,2\} must be written samer@2: as "cref(x,1,2)". samer@2: \item Field referencing using dot (.), eg x.thing - currently resolved samer@2: by using hash (\#) operator, eg x\#thing. samer@2: \item Using variables as arrays and indexing them. The problem is that samer@2: Prolog doesn't let you write a term with a variable as the head samer@2: functor. samer@2: \end{itemize} samer@2: samer@2: \vspace{0.7cm} samer@2: samer@2: \begin{description} samer@2: \predicate[nondet,multifile]{matlab_init}{2}{-Key, -Cmd:ml_expr} samer@2: Each user-defined clause of \predref{matlab_init}{2} causes \arg{Cmd} to be executed samer@2: whenever a new Matlab session is started. samer@2: samer@2: \predicate[nondet,multifile]{matlab_path}{2}{-Key, -Path:list(atom)} samer@2: Each user-defined clause of \predref{matlab_path}{2} causes the directories in \arg{Path} samer@2: to be added to the Matlab path of every new Matlab session. Directories samer@2: are relative to the root directory as returned by Matlab function proot. samer@2: samer@2: \predicate[nondet,multifile]{pl2ml_hook}{2}{+X:term, -Y:ml_expr} samer@2: Clauses of \predref{pl2ml_hook}{2} allow for extensions to the Matlab expression samer@2: language such that \verb|V[$X] = V[Y]| if \verb$pl2ml_hook(X,Y)$. samer@2: samer@2: \predicate[det]{ml_open}{3}{+Id:ml_eng, +Host:atom, +Options:list(_)} samer@2: \nodescription samer@2: \predicate[det]{ml_open}{2}{+Id:ml_eng, +Host:atom} samer@2: \nodescription samer@2: \predicate[det]{ml_open}{1}{+Id:ml_eng} samer@2: Start a Matlab session on the given host. If \arg{Host}=localhost samer@2: or the name of the current current host as returned by \predref{hostname}{1}, samer@2: then a Matlab process is started directly. Otherwise, it is samer@2: started remotely via SSH. \arg{Options} defaults to []. \arg{Host} defaults to samer@2: localhost. samer@2: samer@2: Start a Matlab session on the specified host using default options. samer@2: If \arg{Host} is not given, it defaults to localhost. Session will be samer@2: associated with the given \arg{Id}, which should be an atom. See \predref{ml_open}{3}. samer@2: samer@2: Valid options are samer@2: samer@2: \begin{description} samer@2: \termitem{noinit}{} samer@2: If present, do not run initialisation commands specified by samer@2: \predref{matlab_path}{2} and \predref{matlab_init}{2} clauses. Otherwise, do run them. samer@2: \end{description} samer@2: samer@2: \begin{description} samer@2: \termitem{debug}{In, Out} samer@2: if present, Matlab is started in a script which captures standard samer@2: input and output to files In and Out respectively. samer@2: samer@2: [What if session is already open and attached to \arg{Id}?] samer@2: \end{description} samer@2: samer@2: \predicate[det]{ml_close}{1}{+Id:ml_eng} samer@2: Close Matlab session associated with \arg{Id}. samer@2: samer@2: \predicate[det]{ml_exec}{2}{+Id:ml_eng, +Expr:ml_expr} samer@2: Execute Matlab expression without returning any values. samer@2: samer@2: \predicate[det]{ml_eval}{4}{+Id:ml_eng, +Expr:ml_expr, +Types:list(type), -Res:list(ml_val)} samer@2: Evaluate Matlab expression binding return values to results list \arg{Res}. This new samer@2: form uses an explicit output types list, so \arg{Res} can be completely unbound on entry samer@2: even when multiple values are required. samer@2: samer@2: \predicate[semidet]{ml_test}{2}{+Id:ml_eng, +X:ml_expr(bool)} samer@2: Succeeds if \arg{X} evaluates to true in Matlab session \arg{Id}. samer@2: samer@2: \predicate[det]{===}{2}{Y:ml_vals(A), X:ml_expr(A)} samer@2: Evaluate Matlab expression \arg{X} as in \predref{ml_eval}{4}, binding one or more return values samer@2: to \arg{Y}. If \arg{Y} is unbound or a single ml_val(_), only the first return value is bound. samer@2: If \arg{Y} is a list, multiple return values are processed. samer@2: samer@2: \predicate[det]{??}{1}{X:ml_expr(_)} samer@2: Execute Matlab expression \arg{X} as with \predref{ml_exec}{2}, without returning any values. samer@2: samer@2: \predicate[semidet]{???}{1}{X:ml_expr(bool)} samer@2: Evaluate Matlab boolean expression \arg{X} as with \predref{ml_test}{2}. samer@2: samer@2: \predicate[det]{ml_debug}{1}{+Flag:boolean} samer@2: Set or reset debug state. \verb$ml_debug(true)$ causes formatted Matlab samer@2: statements to be printed before being sent to Matlab engine. samer@2: samer@2: \predicate[det]{term_mlstring}{3}{+Id:ml_eng, +X:ml_expr, -Y:list(code)} samer@2: Convert term representing Matlab expression to a list of character codes. samer@2: samer@2: \predicate[det]{term_texatom}{2}{+X:tex_expr, -Y:atom} samer@2: Convert term representing TeX expression to a string in atom form. samer@2: samer@2: \predicate[semidet]{wsvar}{3}{+X:ws_blob(A), -Nm:atom, -Id:ml_eng} samer@2: True if \arg{X} is a workspace variable in Matlab session \arg{Id}. samer@2: Unifies \arg{Nm} with the name of the Matlab variable. samer@2: samer@2: \predicate[det]{dropmat}{2}{+Id:ml_id, +Mat:ml_loc} samer@2: Deleting MAT file from matbase. samer@2: samer@2: \predicate[det]{exportmat}{3}{+Id:ml_id, +Mat:ml_loc, +Dir:atom} samer@2: Export specified MAT file from matbase to given directory. samer@2: samer@2: \predicate[nondet]{matbase_mat}{2}{+Id:ml_eng, -X:ml_loc} samer@2: Listing mat files actually in matbase at given root directory. samer@2: samer@2: \predicate[det]{persist_item}{2}{+X:ml_expr(A), -Y:ml_expr(A)} samer@2: Convert Matlab expression to persistent form not dependent on samer@2: current Matlab workspace or MX arrays in Prolog memory space. samer@2: Large values like arrays and structures are saved in the matbase samer@2: replaced with matbase locators. Scalar values are converted to samer@2: literal numeric values. Character strings are converted to Prolog atoms. samer@2: Cell arrays wrapped in the \predref{wsseq}{1} functor are converted to literal samer@2: form. samer@2: samer@2: NB. any side effects are undone on backtracking -- in particular, any samer@2: files created in the matbase are deleted. samer@2: samer@2: \predicate[det]{mhelp}{1}{+Name:atom} samer@2: Lookup Matlab help on the given name. Equivalent to executing help(`X). samer@2: samer@2: \predicate[det]{compileoptions}{2}{+Opts:list(ml_options), -Prefs:ml_expr(options)} samer@2: Convert list of option specifiers into a Matlab expression representing samer@2: options (ie a struct). Each specifier can be a Name:Value pair, a name samer@2: to be looked up in the \predref{optionset}{2} predicate, a nested list of ml_options samer@2: compileoptions :: list (optionset \Sbar{} atom:value \Sbar{} struct) \Sifthen{} struct. samer@2: NB. option types are as follows: samer@2: samer@2: \begin{code} samer@2: X :: ml_options :- optionset(X,_). samer@2: X :: ml_options :- X :: ml_option(_). samer@2: X :: ml_options :- X :: list(ml_options). samer@2: X :: ml_options :- X :: ml_expr(struct(_)). samer@2: samer@2: ml_option(A) ---> atom:ml_expr(A). samer@2: \end{code} samer@2: samer@2: \predicate[det]{multiplot}{2}{+Type:ml_plot, +Cmds:list(ml_expr(_))} samer@2: \nodescription samer@2: \predicate[det]{multiplot}{3}{+Type:ml_plot, +Cmds:list(ml_expr(_)), -Axes:list(ml_val(handle))} samer@2: Executes plotting commands in \arg{Cmds} in multiple figures or axes as determined samer@2: by \arg{Type}. Valid types are: samer@2: samer@2: \begin{description} samer@2: \termitem{figs}{Range} samer@2: Executes each plot in a separate figure, Range must be P..Q where P samer@2: and Q are figure numbers. samer@2: \termitem{vertical}{} samer@2: Executes each plot in a subplot; samer@2: subplots are arranged vertically top to bottom in the current figure. samer@2: \termitem{horizontal}{} samer@2: Executes each plot in a subplot; samer@2: subplots are arranged horizontally left to right in the current figure. samer@2: \termitem{\Sdot}{Type, [link(Axis)]} samer@2: As for multplot type \arg{Type}, but link X or Y axis scales as determined by Axis, samer@2: which can be `x, `y, or `xy. samer@2: \end{description} samer@2: samer@2: Three argument form returns a list containing the Matlab handles to axes objects, samer@2: one for each plot. samer@2: samer@2: \predicate[semidet,multifile]{optionset}{2}{+Key:term, -Opts:list(ml_options)} samer@2: Extensible predicate for mapping arbitrary terms to a list of options samer@2: to be processed by \predref{compileoptions}{2}. samer@2: \end{description} samer@2: samer@2: samer@2: \printindex samer@2: \end{document}