Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Finn Teegen
curry-tools
Commits
574bb5e8
Commit
574bb5e8
authored
Mar 16, 2016
by
Michael Hanus
Browse files
Manual for CurryCheck extended
parent
b3e38b36
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
128 additions
and
8 deletions
+128
-8
currycheck/Docs/manual.tex
currycheck/Docs/manual.tex
+117
-7
currycheck/Examples/UsageErrors.curry
currycheck/Examples/UsageErrors.curry
+3
-0
currytest/Docs/manual.tex
currytest/Docs/manual.tex
+8
-1
No files found.
currycheck/Docs/manual.tex
View file @
574bb5e8
\section
{
CurryCheck: A Tool for Testing Curry Programs
}
\section
{
CurryCheck: A Tool for Testing Curry Programs
}
\label
{
sec-currycheck
}
CurryCheck is a tool that supports the automation of
CurryCheck
\index
{
CurryCheck
}
\index
{
testing programs
}
\index
{
program!testing
}
is a tool that supports the automation of
testing Curry programs.
testing Curry programs.
The tests to be executed can be unit tests as well as
The tests to be executed can be unit tests as well as
property tests parameterized over some arguments.
property tests parameterized over some arguments.
...
@@ -42,6 +44,8 @@ Note that each property is defined as a Curry operation
...
@@ -42,6 +44,8 @@ Note that each property is defined as a Curry operation
where the arguments are the parameters of the property.
where the arguments are the parameters of the property.
Altogether, our program is as follows:
Altogether, our program is as follows:
\begin{curry}
\begin{curry}
module Rev(rev) where
import Test.EasyCheck
import Test.EasyCheck
rev :: [a] -> [a]
rev :: [a] -> [a]
...
@@ -72,11 +76,11 @@ Since the operation \code{rev} is polymorphic,
...
@@ -72,11 +76,11 @@ Since the operation \code{rev} is polymorphic,
the property
\code
{
revRevIsId
}
is also polymorphic in its argument.
the property
\code
{
revRevIsId
}
is also polymorphic in its argument.
In order to select concrete values to test this property,
In order to select concrete values to test this property,
CurryCheck replaces such polymorphic tests by defaulting the type
CurryCheck replaces such polymorphic tests by defaulting the type
variable to
\code
{
Ordering
}
(the actual default type can also be set by a
variable to
prelude type
\code
{
Ordering
}
command-line flag).
(the actual default type can also be set by a
command-line flag).
If we want to test this property on integers numbers,
If we want to test this property on integers numbers,
we can explicitly provide a type signature,
we can explicitly provide a type signature,
where
\code
{
Prop
}
i
s the type of test
s
:
where
\code
{
Prop
}
denote
s the type of
a
test:
\begin{curry}
\begin{curry}
revRevIsId :: [Int] -> Prop
revRevIsId :: [Int] -> Prop
revRevIsId xs = rev (rev xs) -=- xs
revRevIsId xs = rev (rev xs) -=- xs
...
@@ -92,7 +96,8 @@ Hence, \code{currycheck} can be easily integrated in tool chains
...
@@ -92,7 +96,8 @@ Hence, \code{currycheck} can be easily integrated in tool chains
for automatic testing.
for automatic testing.
In order to support the inclusion of properties in the source code,
In order to support the inclusion of properties in the source code,
the operations defined the properties do not have to be exported.
the operations defined the properties do not have to be exported,
as show in the module
\code
{
Rev
}
above.
Hence, one can add properties to any library and export only
Hence, one can add properties to any library and export only
library-relevant operations. To test these properties,
library-relevant operations. To test these properties,
CurryCheck creates a copy of the library where all operations
CurryCheck creates a copy of the library where all operations
...
@@ -121,7 +126,7 @@ if the multi-set of values of both sides are equal.
...
@@ -121,7 +126,7 @@ if the multi-set of values of both sides are equal.
Hence, this operator can be used to compare the number
Hence, this operator can be used to compare the number
of computed solutions of two expressions.
of computed solutions of two expressions.
\item
\item
The property
\code
{
always
$
x
$}
is satisfied if all values
$
x
$
are true.
The property
\code
{
always
$
x
$}
is satisfied if all values
of
$
x
$
are true.
\item
\item
The property
\code
{
eventually
$
x
$}
is satisfied if some value
The property
\code
{
eventually
$
x
$}
is satisfied if some value
of
$
x
$
is true.
of
$
x
$
is true.
...
@@ -133,7 +138,7 @@ The property \code{$x$ \# $n$} is satisfied if $x$ has $n$
...
@@ -133,7 +138,7 @@ The property \code{$x$ \# $n$} is satisfied if $x$ has $n$
different values.
different values.
\end{itemize}
\end{itemize}
%
%
For instance, consider theinsertion of an element at an arbitrary
For instance, consider the
insertion of an element at an arbitrary
position in a list:
position in a list:
\begin{curry}
\begin{curry}
insert :: a -> [a] -> [a]
insert :: a -> [a] -> [a]
...
@@ -461,4 +466,109 @@ or we simply reuse the old definition by
...
@@ -461,4 +466,109 @@ or we simply reuse the old definition by
sumUpIsCorrectOnNonNeg = sumUpIsCorrect . nonNeg
sumUpIsCorrectOnNonNeg = sumUpIsCorrect . nonNeg
\end{curry}
\end{curry}
\subsection
{
Checking Contracts and Specifications
}
The expressive power of Curry supports
writing high-level specifications
as well as efficient implementations for a given problem
in the same programming language,
as discussed in
\cite
{
AntoyHanus12PADL
}
.
If a specification or contract is provided for some function,
then CurryCheck automatically generates properties
to test this specification or contract.
Following the notation proposed in
\cite
{
AntoyHanus12PADL
}
,
a
\emph
{
specification
}
\index
{
specification
}
for an operation
$
f
$
is an operation
\code
{$
f
$
'spec
}
of the same type as
$
f
$
.
A
\emph
{
contract
}
\index
{
constract
}
consists
of a pre- and a postcondition, where the precondition could be omitted.
A
\emph
{
precondition
}
\index
{
precondition
}
for an operation
$
f
$
of type
$
\tau
\to
\tau
'
$
is an operation
\begin{curry}
$
f
$
'pre ::
$
\tau
$
->
$
~
$
Bool
\end{curry}
whereas
a
\emph
{
postcondition
}
\index
{
postcondition
}
for
$
f
$
is an operation
\begin{curry}
$
f
$
'post ::
$
\tau
$
->
$
~
\tau
'
$
->
$
~
$
Bool
\end{curry}
which relates input and output values
(the generalization to operations with more than one argument
is straightforward).
As a concrete example, consider again the problem of sorting a list.
We can write a postcondition and a specification for
a sort operation
\code
{
sort
}
and an implementation via quicksort
as follows (where
\code
{
sorted
}
and
\code
{
perm
}
are defined as above):
\begin{curry}
-- Postcondition: input and output lists should have the same length
sort'post xs ys = length xs == length ys
-- Specification:
-- A correct result is a permutation of the input which is sorted.
sort'spec :: [Int] -> [Int]
sort'spec xs | ys == perm xs
&&
sorted ys = ys where ys free
-- An implementation of sort with quicksort:
sort :: [Int] -> [Int]
sort [] = []
sort (x:xs) = sort (filter (<x) xs) ++ [x] ++ sort (filter (>=x) xs)
\end{curry}
%
If we process this program with CurryCheck,
properties to check the specification and postcondition
are automatically generated. For instance,
a specification is satisfied if it yields the same values as
the implementation, and a postcondition is satisfied
if each value computed for some input satisfies the postcondition
relation between input and output. For our example, CurryCheck generates
the following properties (if there are also
preconditions for some operation, these preconditions are used
to restrict the test cases via the condition operater
\ccode
{
==>
}
):
\begin{curry}
sortSatisfiesPostCondition :: [Int] -> Prop
sortSatisfiesPostCondition x =
let r = sort x
in (r == r) ==> always (sort'post x r)
sortSatisfiesSpecification :: [Int] -> Prop
sortSatisfiesSpecification x = sort x <~> sort'spec x
\end{curry}
\subsection
{
Checking Usage of Specific Operations
}
In addition to testing dynamic properties of programs,
CurryCheck also examines the source code of the given
program for unintended uses of specific operations
(these checks can be omitted via the option
\ccode
{
--nosource
}
).
Currently, the following source code checks are performed:
\begin{itemize}
\item
The prelude operation
\ccode
{
=:<=
}
is used to implement
functional patterns
\cite
{
AntoyHanus05LOPSTR
}
. It should not be
used in source programs to avoid unintended uses.
Hence, CurryCheck reports such unintended uses.
\item
Set functions
\cite
{
AntoyHanus09
}
are used to encapsulate
all non-deterministic results of some function in a set structure.
Hence, for each top-level function
$
f
$
of arity
$
n
$
,
the corresponding set function can be expressed in Curry
(via operations defined in the module
\code
{
SetFunctions
}
, see Section~
\ref
{
Library:SetFunctions
}
)
by the application
\ccode
{
set
$
n
$
$
f
$}
(this application is used
in order to extend the syntax of Curry with a specific notation
for set functions).
However, it is not intended to apply the operator
\ccode
{
set
$
n
$}
to lambda abstractions, locally defined operations
or operations with an arity different from
$
n
$
.
Hence, CurryCheck reports such unintended uses of set functions.
\end{itemize}
% LocalWords: CurryCheck
% LocalWords: CurryCheck
currycheck/Examples/UsageErrors.curry
View file @
574bb5e8
...
@@ -14,3 +14,6 @@ test5 = set1 (\x->x) (1?2) -- unintended!
...
@@ -14,3 +14,6 @@ test5 = set1 (\x->x) (1?2) -- unintended!
test6 x = set1 f x -- not allowed since f is not a top-level function
test6 x = set1 f x -- not allowed since f is not a top-level function
where f y = y
where f y = y
test7 xs = set1 (++) xs -- not allowed since (++) has arity 2
currytest/Docs/manual.tex
View file @
574bb5e8
\section
{
CurryTest: A Tool for Testing Curry Programs
}
\section
{
CurryTest: A Tool for Testing Curry Programs
}
\label
{
sec-currytest
}
\paragraph
{
General remark:
}
{
\em
The CurryTest tool described in this section has been replaced
by the more advanced tool CurryCheck (see Section~
\ref
{
sec-currycheck
}
).
CurryTest is still available in
\CYS
but is no more supported.
Hence, it is recommended to use CurryCheck for writing test cases.
}
\bigskip
CurryTest
\index
{
CurryTest
}
\index
{
testing programs
}
\index
{
program!testing
}
CurryTest
\index
{
CurryTest
}
\index
{
testing programs
}
\index
{
program!testing
}
is a simple tool in the
\CYS
distribution to write
is a simple tool in the
\CYS
distribution to write
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment