UNPKG

@ciao-lang/ts-ciao-interface

Version:

Simple Ciao interface for node.

166 lines (147 loc) 13.9 kB
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="theme-color" content="#273f79"/><link rel="stylesheet" href="lpdoc.css" type="text/css"/><script type="text/javascript" src="lpdoc.js"></script><title>Including Editable and Runnable Examples &mdash; The lpdoc Documentation Generator v3.5</title></head><body><div class="lpdoc-page fixleftbar"><a href="#" id="sidebar-toggle-button" class="lpdoc-navbutton"><span id="sidebar-button-arrow">&#9776;</span></a><div id="sidebar" class="lpdoc-sidebar"><div style="height: 40px; margin-left: auto; margin-right: auto"><img src="lpdoc-logo-128_autofig.png" width=auto height=100%></div><div class="lpdoc-nav"><span class="lpdoc-on-right"><a class="lpdoc-navbutton" href="lpdoc_ref_man.html">&#x2191;</a><a class="lpdoc-navbutton" href="lpdoc_examples.html">&#x2190;</a><a class="lpdoc-navbutton" href="factorial_peano_iso_source.html">&#x2192;</a><a class="lpdoc-navbutton" href="lpdoc_ref_mansearch.html">&#x1F50D;</a></span><span><a href="lpdoc_ref_manfulltoc.html">TOC</a></span></div><hr></hr><ul class="lpdoc-itemize-sectpath"><li><a href="lpdoc_ref_man.html">The lpdoc Documentation Generator</a> &raquo;<br/> </li><li><a href=""><strong>Including Editable and Runnable Examples</strong></a> &#9662;<ul><li><a href="factorial_peano_iso_source.html">Source in markdown for the &apos;factorial using ISO-Prolog arithmetic&apos; example</a></li><li><a href="factorial_peano_iso.html">Exercise: factorial using ISO-Prolog arithmetic</a></li></ul></li></ul><hr></hr><em>ON THIS PAGE</em><ul><li><a href="#Runnable Code Blocks">Runnable Code Blocks</a></li><li><a href="#Examples">Examples</a></li></ul></div><div class="lpdoc-main"><div id=""><h1>Including Editable and Runnable Examples</h1> <strong>Author(s):</strong> <a class="lpdoc-idx-anchor" id="The Ciao Development Team" href="lpdoc_ref_mansearch.html#The Ciao Development Team">The Ciao Development Team</a>.<p> This section describes how to include editable and runnable code blocks in <a class="lpdoc-idx-anchor" id="0" href="lpdoc_ref_mansearch.html#LPdoc"><tt>LPdoc</tt></a> documents, to create interactive <em>Active Logic Documents</em> (<a class="lpdoc-idx-anchor" id="1" href="lpdoc_ref_mansearch.html#ALD"><tt>ALD</tt></a>s). These code blocks can either run embedded in the document or be loaded into a playground,<p><div id="Runnable Code Blocks"><h2>Runnable Code Blocks</h2> <p>A <em>runnable</em> code block is a special documentation code block where the language is marked as <tt>ciao_runnable</tt>, as follows:<p><pre class="lpdoc-codeblock">```ciao_runnable ```</pre>These code fragments are automatically rendered as editable cells that can be run, either in place, embedded in the document, for formats/backends that support this (typically <tt>html</tt>), or loaded into a separate playground. Additional commands can be included within the code which allow marking code areas specially to provide different behaviors and functionality. Below, we provide an overview of the available commands along with a brief explanation for each:<p><ul> <p><li><strong>Focus</strong>: The <tt>@begin{focus}</tt> and <tt>@end{focus}</tt> directives are used to selectively show certain sections of the code, while hiding the rest (typically module declarations, imports, or auxiliary code, tests, etc.).<p>To reload or reset the code in this cell, simply <strong>click on the green tick mark</strong> located in the top left corner of the pane. This functionality enables you to reload the code at any time.<p>Example: <pre class="lpdoc-codeblock">```ciao_runnable :- module(_, [qsort/2], []). %! \begin{focus} qsort(Data, Out) :- qsort_(Data, Out, []). qsort_([], R, R). qsort_([X|L], R, R0) :- partition(L, X, L1, L2), qsort_(L2, R1, R0), qsort_(L1, R, [X|R1]). %! \end{focus} partition([],_,[],[]). partition([X|L],Y,[X|L1],L2) :- X =&lt; Y, !, partition(L,Y,L1,L2). partition([X|L],Y,L1,[X|L2]) :- partition(L,Y,L1,L2). ```</pre>Which produces the following cell:<p><pre class="lpdoc-codeblock-runnable">:- module(_, [qsort/2], []). %! \begin{focus} qsort(Data, Out) :- qsort_(Data, Out, []). qsort_([], R, R). qsort_([X|L], R, R0) :- partition(L, X, L1, L2), qsort_(L2, R1, R0), qsort_(L1, R, [X|R1]). %! \end{focus} partition([],_,[],[]). partition([X|L],Y,[X|L1],L2) :- X =&lt; Y, !, partition(L,Y,L1,L2). partition([X|L],Y,L1,[X|L2]) :- partition(L,Y,L1,L2).</pre><li><strong>Queries</strong>: A query cell is specified by a runnable code block where the code begins with <tt>?-</tt>. Example:<p><pre class="lpdoc-codeblock">```ciao_runnable ?- qsort([1,5,4,2,3],X). ```</pre>Which produces:<p><pre class="lpdoc-codeblock-runnable">?- qsort([1,5,4,2,3],X).</pre>There is essentially one toplevel per page; all programs in a given <a class="lpdoc-idx-anchor" id="2" href="lpdoc_ref_mansearch.html#ALD"><tt>ALD</tt></a> page are loaded into this toplevel and all queries in the page are executed in that toplevel, against all the code (possibly separate modules) that has been loaded into the toplevel at that point.<p><li>Interactive <strong>exercises</strong>: Interactive cells can be easily configured to serve as exercises, where the reader can provide or edit the code, which can then be played with or checked automaticaly against expectations. Instructions can be added either in the text surrounding the ecxecutable cell(s), or as comments in the code itself in the cells. The code can also contain hints to the solution, such as partially completed predicates, predicates that need fixing, etc. The behavior of the code can be checked for example by including test assertions (unit tests) in the code. Clicking on the <strong>yellow face</strong> icon executes the code, including the execution of hidden unit tests, which then provide feedback to the reader.<p><p>Segments enclosed within hint directives function similarly to focus segments, and are used typically to offer the hints or instructions mentioned above. However, if the reader requests to see the solution, then, the hint segment will be replaced with the corresponding solution, marked by solution directives.<p>Example: <pre class="lpdoc-codeblock">```ciao_runnable %! \begin{hint} Proposed exercise %! \end{hint} (Optional) Unit tests %! \begin{solution} Solution %! \end{solution} ```</pre></ul> <p><p>The <tt>ciao_runnable</tt> language tag also allows the following additional annotations to interact with the browser using Javascript and/or Prolog code running through WebAssembly.<p><div class="lpdoc-alert"> The following are experimental features whose API may change in future versions. Usage requires knowledge of HTML, Javascript (and some internals of <tt>ciao_playground.js</tt>). </div> <p><ul> <p><li><strong>jseval</strong>: Escape mechanism to allow execution of arbitrary Javascript code. The text within <tt>jseval</tt> is executed at document initialization (following the sequential order of playground cells) as a Javascript asynchronous function. Typically this is done as: <pre class="lpdoc-codeblock">```ciao_runnable %! \begin{jseval} async() =&gt; { &lt;&lt;JSCODE&gt;&gt; } %! \end{jseval} ```</pre>Example (when included, the HTML document will turn upside-down): <pre class="lpdoc-codeblock">```ciao_runnable %! \begin{jseval} async() =&gt; { document.body.style.transform = &quot;rotate(180deg);&quot; } %! \end{jseval} ```</pre><li><strong>dynpreview</strong>: Allow dynamically generated HTML fragments. See for example <tt>catalog_ui/bundles_dyn.pl</tt> in the website bundle. It requires a JSON structure that is passed to <tt>setup_dynpreview</tt> (see <tt>ciao_playground.js</tt>). For example:<p><pre class="lpdoc-codeblock">```ciao_runnable %! \begin{dynpreview} { render_pred: &apos;bundles_dyn:render&apos;, state_hash: true, depends: [&apos;ciaowasm&apos;, &apos;website&apos;, &apos;lpdoc&apos;], on_init: [&apos;use_module(catalog_ui(bundles_dyn))&apos;] } %! \end{dynpreview} ```</pre>The <tt>render_pred</tt> field specifies the predicate that will generate the HTML contents (as a string, e.g., using <a class="lpdoc-idx-anchor" id="3" href="lpdoc_ref_mansearch.html#pillow"><tt>pillow</tt></a>). The <tt>state_hash</tt> field specifies if the URL hash is passed as parameter (e.g., to maintain a state). The rest of fields indicate the bundle dependencies and initialization goals.<p></ul> <p></div><div id="Examples"><h2>Examples</h2> <p>The following example shows a programming task with some initial hints, a valid solution (there may be others), and some tests to validate the user code:<p><pre class="lpdoc-codeblock">```ciao_runnable :- module(_, _, [assertions]). :- test factorial(A, B) : (A = 0) =&gt; (B = 1) + (not_fails, is_det). :- test factorial(A, B) : (A = 1) =&gt; (B = 1) + (not_fails, is_det). :- test factorial(A, B) : (A = 2) =&gt; (B = 2) + (not_fails, is_det). :- test factorial(A, B) : (A = 3) =&gt; (B = 6) + (not_fails, is_det). :- test factorial(A, B) : (A = 4) =&gt; (B = 24) + (not_fails, is_det). :- test factorial(A, B) : (A = 5) =&gt; (B = 120) + (not_fails, is_det). :- test factorial(A, B) : (A = 0, B = 0) + (fails, is_det). :- test factorial(A, B) : (A = 5, B = 125) + (fails, is_det). :- test factorial(A, B) : (A = -1) + (fails, is_det). %! \begin{hint} % TASK 1 - Rewrite with Prolog arithmetic factorial(0,s(0)). % TODO: Replace s(0) by 1 factorial(M,F) :- % TODO: Make sure that M &gt; 0 M = s(N), % TODO: Compute N from M using is/2 (note that N is factorial(N,F1), % unbound, so you need to compute N from M!) times(M,F1,F). % TODO: Replace times/3 by a call to is/2 (using *) % When you are done, press the circle (&quot;Run tests&quot;) or the arrow % (&quot;Load into playground&quot;). %! \end{hint} %! \begin{solution} factorial(0,1). factorial(N,F) :- N &gt; 0, N1 is N-1, factorial(N1,F1), F is F1*N. %! \end{solution} ```</pre>This produces the following cell:<p><pre class="lpdoc-codeblock-runnable">:- module(_, _, [assertions]). :- test factorial(A, B) : (A = 0) =&gt; (B = 1) + (not_fails, is_det). :- test factorial(A, B) : (A = 1) =&gt; (B = 1) + (not_fails, is_det). :- test factorial(A, B) : (A = 2) =&gt; (B = 2) + (not_fails, is_det). :- test factorial(A, B) : (A = 3) =&gt; (B = 6) + (not_fails, is_det). :- test factorial(A, B) : (A = 4) =&gt; (B = 24) + (not_fails, is_det). :- test factorial(A, B) : (A = 5) =&gt; (B = 120) + (not_fails, is_det). :- test factorial(A, B) : (A = 0, B = 0) + (fails, is_det). :- test factorial(A, B) : (A = 5, B = 125) + (fails, is_det). :- test factorial(A, B) : (A = -1) + (fails, is_det). %! \begin{hint} % TASK 1 - Rewrite with Prolog arithmetic factorial(0,s(0)). % TODO: Replace s(0) by 1 factorial(M,F) :- % TODO: Make sure that M &gt; 0 M = s(N), % TODO: Compute N from M using is/2 (note that N is factorial(N,F1), % unbound, so you need to compute N from M!) times(M,F1,F). % TODO: Replace times/3 by a call to is/2 (using *) % When you are done, press the circle (&quot;Run tests&quot;) or the arrow % (&quot;Load into playground&quot;). %! \end{hint} %! \begin{solution} factorial(0,1). factorial(N,F) :- N &gt; 0, N1 is N-1, factorial(N1,F1), F is F1*N. %! \end{solution}</pre>The examples shows how tests can be included, hints and solutions provided, etc.<p>The following example illustrates the use of <tt>@begin{focus}</tt> and <tt>@end{focus}</tt> directives to specify that only some parts of the code be shown:<p><pre class="lpdoc-codeblock">```ciao_runnable :- module(_, _, [assertions,sr/bfall]). %! \begin{focus} factorial(0,s(0)). factorial(s(N),F) :- factorial(N,F1), times(s(N),F1,F). %! \end{focus} nat_num(0). nat_num(s(X)) :- nat_num(X). times(0,Y,0) :- nat_num(Y). times(s(X),Y,Z) :- plus(W,Y,Z), times(X,Y,W). plus(0,Y,Y) :- nat_num(Y). plus(s(X),Y,s(Z)) :- plus(X,Y,Z). ```</pre>results in:<p><pre class="lpdoc-codeblock-runnable">:- module(_, _, [assertions,sr/bfall]). %! \begin{focus} factorial(0,s(0)). factorial(s(N),F) :- factorial(N,F1), times(s(N),F1,F). %! \end{focus} nat_num(0). nat_num(s(X)) :- nat_num(X). times(0,Y,0) :- nat_num(Y). times(s(X),Y,Z) :- plus(W,Y,Z), times(X,Y,W). plus(0,Y,Y) :- nat_num(Y). plus(s(X),Y,s(Z)) :- plus(X,Y,Z).</pre>Programs can be modules or &apos;user&apos; (i.e., non-modular) code. The focus facility can be used as shown above to select whether boilerplate lines (such as, e.g., module declarations, imports, auxiliary code, etc.) are shown in the output or not.<p>Finally, the following are examples of runnable and editable queries:<p><pre class="lpdoc-codeblock">```ciao_runnable ?- factorial(X,s(s(s(s(s(s(0))))))). ```</pre>resulting in:<p><pre class="lpdoc-codeblock-runnable">?- factorial(X,s(s(s(s(s(s(0))))))).</pre>As mentioned before, there is essentially one toplevel per page; all programs in a given <a class="lpdoc-idx-anchor" id="4" href="lpdoc_ref_mansearch.html#ALD"><tt>ALD</tt></a> are loaded into this toplevel and all queries in the page are executed in that toplevel, against all the code (possibly separate modules) that has been loaded into the toplevel at that point.<p>You can consult the subparts below to view a complete example, including the full source code and generated output.</div><br/><h2>Subparts</h2><ul><li><a href="factorial_peano_iso_source.html">Source in markdown for the &apos;factorial using ISO-Prolog arithmetic&apos; example</a></li><li><a href="factorial_peano_iso.html">Exercise: factorial using ISO-Prolog arithmetic</a></li></ul></div><div class="lpdoc-footer">Generated with LPdoc using Ciao</div></div><div class="lpdoc-clearer"></div></div></body></html>