UNPKG

@ciao-lang/ts-ciao-interface

Version:

Simple Ciao interface for node.

496 lines (377 loc) 20.6 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>Examples (unittest) &mdash; Run-time Checking, Testing, and Profiling for Ciao</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 class="lpdoc-nav"><span class="lpdoc-on-right"><a class="lpdoc-navbutton" href="unittest.html">&#x2191;</a><a class="lpdoc-navbutton" href="unittest_statistics.html">&#x2190;</a><a class="lpdoc-navbutton" href="profiler_doc.html">&#x2192;</a><a class="lpdoc-navbutton" href="ciaodbg_ref_mansearch.html">&#x1F50D;</a></span><span><a href="ciaodbg_ref_manfulltoc.html">TOC</a></span></div><hr></hr><ul class="lpdoc-itemize-sectpath"><li><a href="ciaodbg_ref_man.html">Run-time Checking, Testing, and Profiling for Ciao</a> &raquo;<br/> </li><li><a href="unittest.html">Unit testing</a> &raquo;<br/> </li><li><a href=""><strong>Examples (unittest)</strong></a></li></ul><hr></hr><em>ON THIS PAGE</em><ul><li><a href="#test_examples.pl">test_examples.pl</a></li><li><a href="#ceval1.pl">ceval1.pl</a></li><li><a href="#ceval2.pl">ceval2.pl</a></li><li><a href="#length.pl">length.pl</a></li><li><a href="#civil_registry.pl">civil_registry.pl</a></li><li><a href="#qsort.pl">qsort.pl</a></li><li><a href="#relationships.pl">relationships.pl</a></li></ul></div><div class="lpdoc-main"><div id=""><h1>Examples (unittest)</h1> <strong>Author(s):</strong> <a class="lpdoc-idx-anchor" id="Edison Mera" href="ciaodbg_ref_mansearch.html#Edison Mera">Edison Mera</a>, <a class="lpdoc-idx-anchor" id="Pedro Lopez" href="ciaodbg_ref_mansearch.html#Pedro Lopez">Pedro L&oacute;pez</a>, <a class="lpdoc-idx-anchor" id="Manuel Hermenegildo" href="ciaodbg_ref_mansearch.html#Manuel Hermenegildo">Manuel Hermenegildo</a>.<p> <strong>Stability: [</strong><strong>beta</strong><strong>] </strong>Most of the functionality is there but it is still missing some testing and/or verification.<p><br/> Some examples of the use of test assertions.<p><div id="test_examples.pl"><h2>test_examples.pl</h2> <p><pre class="lpdoc-codeblock">:- module(test_examples, [ p/1, display1/1, call_test10/1, cut_test5/0, display_fail/0 ], [assertions, nativeprops, basicmodes, rtchecks, unittestdecls, hiord]). :- doc(author, &quot;Edison Mera&quot;). :- doc(author, &quot;Nataliia Stulova&quot;). :- doc(module, &quot;Some examples of unit tests.&quot;). :- use_module(engine(io_basic)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % ---------------------------------------------------------------------- % tests only with preconditions :- test p(A) : (A = c) # &quot;test should pass&quot;. :- test p(A) : (A = d, A = a) # &quot;test should fail (precondition)&quot;. :- test p(A) : throw(exception) # &quot;test should fail (throws exception in precondition)&quot;. :- test p(A) : (A = h) # &quot;test should abort&quot;. % ---------------------------------------------------------------------- % tests with preconditions and computational properties :- test p(A) : (A = a) + not_fails # &quot;test should pass&quot;. :- test p(A) : (A = b) + fails # &quot;test should pass&quot;. :- test p(A) : (A = c) + exception(error(c, _)) # &quot;test should pass&quot;. :- test p(A) : (A = c) + fails # &quot;test should fail&quot;. :- test p(A) : (A = c) + not_fails # &quot;test should fail&quot;. % ---------------------------------------------------------------------- % tests with preconditions and postonditions :- test p(Z) =&gt; (Z = d). % ---------------------------------------------------------------------- % assertions that can be added to all unit tests for p/1 with the % &apos;rtc_entry&apos; unittest option :- check comp p(X) : (X = a) + not_fails. % :- check comp p(X) : (X = b) + not_fails. p(a). % rule succeeds p(b) :- fail. % rule fails p(c) :- throw(error(c, &apos;error c&apos;)). % rule throws an exception p(h) :- halt(1). % rule aborts the execution % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- use_module(library(unittest/unittest_props), [times/2]). % ---------------------------------------------------------------------- % this set of tests demonstrates the correct and incorrect uses of texec % assertions, it only gives examples of passing tests % :- texec display1(A) : (A = hello) # &quot;correct texecassertion, test should pass&quot;. :- texec display1(A) : (A = hello) + times(1) # &quot;correct texec assertion, test should pass&quot;. :- texec display1(A) : (A = hello) + user_output(&quot;hello&quot;) # &quot;incorrect texec assertion, test should pass&quot;. % ---------------------------------------------------------------------- % ---------------------------------------------------------------------- % examples of the alternatives for the texec assertions above % :- test display1(A) : (A = hello) # &quot;test should pass&quot;. :- test display1(A) : (A = hello) + user_output(&quot;bye&quot;) # &quot;test should fail&quot;. % ---------------------------------------------------------------------- display1(A) :- display(A). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- test display_fail + (user_output(&quot;hello&quot;), fails) # &quot;Test OK&quot;. display_fail :- display(hello), fail. :- pred display_fail(A) + (user_output(&quot;hello2&quot;), fails). :- export(display_fail/1). display_fail(_A) :- display(hello), fail. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- use_module(library(write), [write/1]). :- test cut_test5 + (times(3), user_output(&quot;Cut disjunction&quot;), fails) # &quot;Test OK&quot;. cut_test5 :- (! ; write(&apos;No&apos;)), write(&apos;Cut disjunction&apos;), fail. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- test call_test10(X) : (X=(write(3), call(1))) + ( user_output(&quot;output&quot;), exception(error(type_error(callable, 1), &apos;in metacall&apos;)) ) # &quot;Wrong test&quot;. :- meta_predicate call_test10(goal). call_test10(X) :- call(X). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- export(qs/2). :- pred qs(+list(int), -list(int)) + is_det. qs(A, A). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% tests below cover most of scenarios of the unit test expansion %% (missing: tests that take into account different values of prolog flags %% rtchecks_predloc and rtchecks_asrloc (see rtchecks_tr:combine_locators/6) %% for the reason behind). %% tests for different uses of GP properties in texec assertions :- use_module(library(unittest/unittest_props), [try_sols/2]). :- export(case_tx/2). % processing texec as texec :- texec case_tx(A, AB) : (A = a) # &quot;test should pass&quot;. :- texec case_tx(A, AB) : (A = a) + ( times(2), try_sols(2) ) # &quot;test should pass&quot;. % processing texec as test :- texec case_tx(A, AB) : (A = a) + is_det # &quot;test should fail, bug: true&amp;false test&quot;. :- texec case_tx(A, AB) : (A = a) + (try_sols(2), non_det) # &quot;test should pass&quot;. case_tx(a, a). case_tx(a, b). % ---------------------------------------------------------------------- %% tests for different uses of AP and GP properties in test assertions :- export(case_ts/2). :- test case_ts(X, Y) : (X = a) # &quot;test should pass&quot;. :- test case_ts(X, Y) : (X = a) + try_sols(1) # &quot;test should pass&quot;. :- test case_ts(X, Y) : (X = b) + is_det # &quot;test should pass&quot;. :- test case_ts(X, Y) : (X = a) =&gt; (Y = b) + try_sols(1) # &quot;test should fail&quot;. :- test case_ts(X, Y) : (X = b) =&gt; (Y = a ; Y = b) + is_det # &quot;test should pass&quot;. % ---------------------------------------------------------------------- %% checks for the properties in the assertions are added to the unit %% tests for case_ts/2 iff this module does not include the rtchecks %% package. To see the effects of this assertions remove the rtchecks %% package from the package list and run the tests for this module %% wuth the [rtc_entry] test option. If you do not remove the %% package, the assertions below will be simply turned into rtchecks. % :- pred case_ts(X,Y) : atm(X) =&gt; int(Y) # &quot;makes unit tests fail&quot;. % :- pred case_ts(X,Y) : atm(X) =&gt; gnd(Y) # &quot;does not affect unit tests&quot;. case_ts(a, a). case_ts(a, b). case_ts(b, b). </pre> <p></div><div id="ceval1.pl"><h2>ceval1.pl</h2> <p><pre class="lpdoc-codeblock">:- module(ceval1, [ceval/2], [assertions, regtypes, nativeprops]). :- doc(author, &quot;Edison Mera&quot;). :- doc(module, &quot;This example illustrates how the unified approach for static verification, run-time checking, and unit testing works. It captures the situation in which the programmer changes the main functor of a data structure. In this case, the regular type complex c(A, B) is renamed to cm(A, B). This file contains the initial program.&quot;). :- entry ceval/2 : gnd * var. :- regtype complex/1. :- export(complex/1). complex(c(A, B)) :- num(A), num(B). :- test ceval(A, B) : (A = c(3, 4) + c(1, 2) - c(2, 3)) =&gt; (B = c(2, 3)) + (not_fails, is_det). :- test ceval(A, B) : (A = c(3, 4) * c(1, 2) / c(1, 2)) =&gt; (B = c(3.0, 4.0)) + (not_fails, is_det). :- check pred ceval/2 : gnd * term =&gt; gnd * complex. ceval(A, A) :- complex(A), !. ceval(A+B, C) :- ceval(A, CA), ceval(B, CB), add(CA, CB, C). ceval(A-B, C) :- ceval(A, CA), ceval(B, CB), sub(CA, CB, C). ceval(A*B, C) :- ceval(A, CA), ceval(B, CB), mul(CA, CB, C). ceval(A/B, C) :- ceval(A, CA), ceval(B, CB), div(CA, CB, C). :- pred add/3 : complex * complex * var =&gt; complex * complex * complex. add(c(A1, B1), c(A2, B2), c(A, B)) :- A is A1 + A2, B is B1 + B2. :- pred sub/3 : complex * complex * var =&gt; complex * complex * complex. sub(c(A1, B1), c(A2, B2), c(A, B)) :- A is A1 - A2, B is B1 - B2. :- pred mul/3 : complex * complex * var =&gt; complex * complex * complex. mul(c(A1, B1), c(A2, B2), c(A, B)) :- A is A1*A2 - B1*B2, B is A1*B2 + B1*A2. :- pred div/3 : complex * complex * var =&gt; complex * complex * complex. div(c(A1, B1), c(A2, B2), c(A, B)) :- D is A2*A2 + B2*B2, A is (A1*A2 + B1*B2) / D, B is (A2*B1 - A1*B2) / D. </pre> <p></div><div id="ceval2.pl"><h2>ceval2.pl</h2> <p><pre class="lpdoc-codeblock">:- module(ceval2, [ceval/2], [assertions, regtypes, nativeprops]). :- doc(author, &quot;Edison Mera&quot;). :- doc(module, &quot;This example illustrates how the unified approach for static verification, run-time checking, and unit testing works. It captures the situation in which the programmer changes the main functor of a data structure. In this case, the regular type complex c(A, B) is renamed to cm(A, B). This file contains the renamed program (with a bug).&quot;). :- entry ceval/2 : gnd * var. :- regtype complex/1. :- export(complex/1). complex(cm(A, B)) :- num(A), num(B). :- false test ceval(A, B) : (A = cm(3, 4) + cm(1, 2) - cm(2, 3)) =&gt; (B = cm(2, 3)) + (not_fails, is_det). :- test ceval(A, B) : (A = cm(3, 4) * cm(1, 2) / cm(1, 2)) =&gt; (B = cm(3.0, 4.0)). :- check pred ceval/2 : gnd * term =&gt; gnd * complex. ceval(A, A) :- complex(A), !. ceval(A+B, C) :- ceval(A, CA), ceval(B, CB), add(CA, CB, C). ceval(A-B, C) :- ceval(A, CA), ceval(B, CB), sub(CA, CB, C). ceval(A*B, C) :- ceval(A, CA), ceval(B, CB), mul(CA, CB, C). ceval(A/B, C) :- ceval(A, CA), ceval(B, CB), div(CA, CB, C). :- pred add/3 : complex * complex * var =&gt; complex * complex * complex. add(cm(A1, B1), cm(A2, B2), cm(A, B)) :- A is A1 + A2, B is B1 + B2. :- pred sub/3 : complex * complex * var =&gt; complex * complex * complex. sub(cm(A1, B1), cm(A2, B2), c(A, B)) :- % You forgot to rename c to cm! A is A1 - A2, B is B1 - B2. :- pred mul/3 : complex * complex * var =&gt; complex * complex * complex. mul(cm(A1, B1), cm(A2, B2), cm(A, B)) :- A is A1*A2 - B1*B2, B is A1*B2 + B1*A2. :- pred div/3 : complex * complex * var =&gt; complex * complex * complex. div(cm(A1, B1), cm(A2, B2), cm(A, B)) :- D is A2*A2 + B2*B2, A is (A1*A2 + B1*B2) / D, B is (A2*B1 - A1*B2) / D. </pre> <p></div><div id="length.pl"><h2>length.pl</h2> <p><pre class="lpdoc-codeblock">:- module(length, [length/2, concat/3], [assertions, isomodes, metatypes, hiord, nativeprops]). :- doc(author, &quot;Alvaro Sevilla San Mateo&quot;). length([], 0). length([_|T], N) :- length(T, N0), N is N0 + 1. concat([], L, L). concat([X|L1], L2, [X|L3]) :- concat(L1, L2, L3). :- test length(X, Y) : (X = [1, 2, 3], Y = 3) + not_fails. :- test length(X, Y) : (X = [a, b, c, d, e], Y = 5) + not_fails. :- test length(X, Y) : (X = [], Y = 0) + not_fails. :- test length(X, Y) : (X = [a, b, c, d, e], Y = 5) + not_fails. :- test length(X, Y) : (X = [a, b, c], Y = 5) + fails. :- test length(X, Y) : (X = [a, b, c, d], Y = 5) + fails. :- test concat(A, B, C) : (A = [1, 2], B = [3], C = [1, 2, 3]) + not_fails. :- test concat(A, B, C) : (A = [1, 2], B = [3], var(C)) =&gt; (C=[1, 2, 3]) + not_fails. </pre> <p></div><div id="civil_registry.pl"><h2>civil_registry.pl</h2> <p><pre class="lpdoc-codeblock">:- module(civil_registry, [profession/1, surname/1, sevillian/1, family_income/1, married/2, salary/2], [assertions, isomodes, metatypes, hiord, nativeprops]). :- doc(author, &quot;Alvaro Sevilla San Mateo&quot;). family_information(husband(name(antonio, garcia, fernandez), profession(architect), salary(300000)), wife(name(ana, ruiz, lopez), profession(teacher), salary(120000)), address(sevilla)). family_information(husband(name(luis, alvarez, garcia), profession(architect), salary(400000)), wife(name(ana, romero, soler), profession(housewife), salary(0)), address(sevilla)). family_information(husband(name(bernardo, bueno, martinez), profession(teacher), salary(120000)), wife(name(laura, rodriguez, millan), profession(doctor), salary(250000)), address(cuenca)). family_information(husband(name(miguel, gonzalez, ruiz), profession(businessman), salary(400000)), wife(name(belen, salguero, cuevas), profession(housewife), salary(0)), address(dos_hermanas)). profession(X) :- family_information(husband(_,profession(X),_),_,_). profession(X) :- family_information(_,wife(_,profession(X),_),_). :- test profession(X) : (X = doctor) + not_fails. :- test profession(X) : (X = businessman) + not_fails. :- test profession(X) : (X = computer_scientist) + fails. surname(X) :- family_information(husband(name(_, X, _), _, _), _, _). surname(X) :- family_information(_, wife(name(_, X, _), _, _), _). :- test surname(X) : (X = alvarez) + not_fails. :- test surname(X) : (X = salguero) + not_fails. :- test surname(X) : (X = sanchez) + fails. sevillian(X) :- family_information(husband(X, _, _), _, address(sevilla)). sevillian(X) :- family_information(_, wife(X, _, _), address(sevilla)). :- test sevillian(X) : (X = name(miguel, gonzalez, ruiz)) + fails. :- test sevillian(X) : (X = name(belen, salguero, cuevas)) + fails. :- test sevillian(X) : (X = name(pedro, sanchez, rodriguez)) + fails. :- test sevillian(X) : (X = name(antonio, garcia, fernandez)) + not_fails. family_income(X) :- family_information( husband(_, _, salary(N1)), wife(_, _, salary(N2)), _), X is N1+N2. :- test family_income(X) : (X = 400000) + not_fails. :- test family_income(X) : (X = 370000) + not_fails. :- test family_income(X) : (X = 100) + fails. married(X, Y) :- family_information( husband(name(X, _, _), _, _), wife(name(Y, _, _), _, _), _). :- test married(X, Y) : (X = antonio, Y = ana) + not_fails. :- test married(X, Y) : (X = miguel, Y = belen) + not_fails. :- test married(X, Y) : (X = antonio, Y = maria) + fails. salary(X, Y) :- family_information(husband(X, _, salary(Y)), _, _). salary(X, Y) :- family_information(_, wife(X, _, salary(Y)), _). :- test salary(X, Y) : (X = name(luis, alvarez, garcia), Y = 400000) + not_fails. :- test salary(X, Y) : (X = name(laura, rodriguez, millan), Y = 250000) + not_fails. :- test salary(X, Y) : (X = ana, Y = 100) + fails. </pre> <p></div><div id="qsort.pl"><h2>qsort.pl</h2> <p><pre class="lpdoc-codeblock">:- module(_, [qsort/2], [assertions, nativeprops]). :- doc(author, &quot;Edison Mera&quot;). :- doc(module, &quot;This example illustrates how the unified approach for static verification, run-time checking and unit testing works. In this case, a bug have been introduced: in the call to append/3 by qsort/2, variables R1 and R2 are swapped. Then we prove statically part of the assertions, for the part that cannot be verified statically we generate run-time checks, and finally, the program also has a test attached that exercises the run-time checks.&quot;). :- prop sorted_num_list/1. :- export(sorted_num_list/1). sorted_num_list([]). sorted_num_list([X]) :- number(X). sorted_num_list([X, Y|Z]) :- number(X), number(Y), X&lt;Y, sorted_num_list([Y|Z]). :- calls partition(A, B, C, D) : (ground(A), ground(B)). :- comp partition(A, B, C, D) : (list(num, A)) + (not_fails, is_det). :- success partition(A, B, C, D) =&gt; (ground(C), list(num, D)). partition([], _B, [], []). partition([E|R], C, [E|Left1], Right) :- E &lt; C, !, partition(R, C, Left1, Right). partition([E|R], C, Left, [E|Right1]) :- E &gt;= C, partition(R, C, Left, Right1). :- calls append(A, B, C) : (list(num, A), list(num, B)). append([], X, X). append([H|X], Y, [H|Z]) :- append(X, Y, Z). :- entry qsort(A, B) : (list(num, A), ground(A)). :- test qsort(A, B) : (A = [5, 7, 2, 4, 3]) =&gt; (B = [2, 3, 4, 5, 7]). :- calls qsort(A, B) : list(num, A). :- comp qsort(A, B) : (list(num, A), ground(A), var(B)) + is_det. :- success qsort(A, B) =&gt; (ground(B), sorted_num_list(B)). qsort([X|L], R) :- partition(L, X, L1, L2), qsort(L2, R2), qsort(L1, R1), append(R2, [X|R1], R). % There is a bug here!!! qsort([], []). </pre> <p></div><div id="relationships.pl"><h2>relationships.pl</h2> <p><pre class="lpdoc-codeblock">:- module(relationships, [father/2, son/2, grandfather/2, brother/2, fsb/2], [assertions, isomodes, metatypes, hiord, nativeprops]). :- doc(author, &quot;Alvaro Sevilla San Mateo&quot;). father(&apos;juan&apos;, &apos;maria&apos;). % juan is the father of maria father(&apos;pablo&apos;, &apos;juan&apos;). % pablo is the father of juan father(&apos;pablo&apos;, &apos;marcela&apos;). father(&apos;carlos&apos;, &apos;debora&apos;). % A is the son of B if B the father of A son(A, B) :- father(B, A). % A is the grandfather of B if A is the father of C and C is the father of B grandfather(A, B) :- father(A, C), father(C, B). % A and B are brothers if the father of A is also the father of B and A and B are different persons brother(A, B) :- father(C, A), father(C, B), A \== B. % A and B are fsb if A is the father, son, or brother of B fsb(A, B) :- father(A, B). fsb(A, B) :- son(A, B). fsb(A, B) :- brother(A, B). % Tests :- test fsb(A, B) : (A = &apos;juan&apos;, B = &apos;marcela&apos;) + not_fails. :- test fsb(A, B) : (A = &apos;pedro&apos;, B = &apos;pedro&apos;) + not_fails. :- test fsb(A, B) : (A = &apos;debora&apos;, B = &apos;carlos&apos;) + fails. :- test fsb(A, B) : (A = &apos;debora&apos;, B = &apos;nadie&apos;) + not_fails. :- test brother(A, B) : (A = &apos;debora&apos;, B = &apos;carlos&apos;) + not_fails. </pre></div><br/></div><div class="lpdoc-footer">Generated with LPdoc using Ciao</div></div><div class="lpdoc-clearer"></div></div></body></html>