Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
curry-packages
currycheck
Commits
58c70546
Commit
58c70546
authored
Feb 11, 2018
by
Michael Hanus
Browse files
AUTOMATIC -> AUTOSELECT, manual updated
parent
5a4ec6e7
Changes
5
Hide whitespace changes
Inline
Side-by-side
docs/main.tex
View file @
58c70546
...
...
@@ -80,6 +80,12 @@ S.~Antoy and M.~Hanus.
Aspects of Declarative Languages (PADL 2012)
}
, pages 33--47. Springer LNCS
7149, 2012.
\bibitem
{
AntoyHanus18FLOPS
}
S.~Antoy and M.~Hanus.
\newblock
Equivalence checking of non-deterministic operations.
\newblock
In
{
\em
Proc. of the 14th International Symposium on
Functional and Logic Programming (FLOPS 2018)
}
, to appear in Springer LNCS.
\bibitem
{
ChristiansenFischer08FLOPS
}
J.~Christiansen and S.~Fischer.
\newblock
{
EasyCheck
}
- test data for free.
...
...
docs/manual.tex
View file @
58c70546
...
...
@@ -550,11 +550,12 @@ sortSatisfiesSpecification x = sort x <~> sort'spec x
\subsection
{
Checking Equivalence of Operations
}
CurryCheck supports also equivalence
check
s for operations.
CurryCheck supports also equivalence
test
s for operations.
Two operations are considered as
\emph
{
equivalent
}
if they
can be replaced by each other in any possible context
without changing the computed values (see
\cite
{
AntoyHanus12PADL
}
for a precise definition).
without changing the computed values (this is also called
\emph
{
contextual equivalence
}
and precisely defined in
\cite
{
AntoyHanus12PADL
}
for functional logic programs).
For instance, the Boolean operations
\begin{curry}
f1 :: Bool -> Bool f2 :: Bool -> Bool
...
...
@@ -575,16 +576,16 @@ property combinator \code{<=>}:
f1
_
equiv
_
f2 = f1 <=> f2
g1
_
equiv
_
g2 = g1 <=> g2
\end{curry}
Each
argument of this combinator must be a defined operation
The left and right
argument of this combinator must be a defined operation
or a defined operation with a type annotation in order to specify
the argument types used for checking this property.
CurryCheck transforms such properties into properties
where both operations are compared w.r.t.
\
all partial
values and partial results.
The details are described in
an upcoming paper
.
The details are described in
\cite
{
AntoyHanus18FLOPS
}
.
It should be noted that CurryCheck can
also check
It should be noted that CurryCheck can
test
the equivalence of non-terminating operations provided
that they are
\emph
{
productive
}
, i.e., always generate
(outermost) constructors after a finite number of steps
...
...
@@ -598,8 +599,8 @@ ints2 n = n : ints2 (n+2)
-- This property will be falsified by CurryCheck:
ints1
_
equiv
_
ints2 = ints1 <=> ints2
\end{curry}
This is done by guessing depth-bounds
and
comp
ar
ing
the result
s
of both operations
up to th
is
depth-bound.
This is done by
iteratively
guessing depth-bounds
,
comp
ut
ing
both operation
s
up to th
ese
depth-bound
s, and comparing the computed results
.
Since this might be a long process, CurryCheck supports
a faster comparison of operations when it is known
that they are terminating.
...
...
@@ -625,7 +626,7 @@ isort xs = idSorted (perm xs)
idSorted [x] = [x]
idSorted (x:y:ys) | x<=y = x : idSorted (y:ys)
\end{curry}
We can
check
the equivalence of both operations by
We can
test
the equivalence of both operations by
specializing both operations on some ground type (otherwise,
the type checker reports an error due to an unspecified
type
\code
{
Ord
}
context):
...
...
@@ -640,12 +641,39 @@ psort_equiv_isort'TERMINATE = psort <=> (isort :: [Int] -> [Int])
\end{curry}
Now a counter example is found by the 21th test.
One can also tell CurryCheck to analyze the operations for termination.
If CurryCheck is invoked with the option
\ccode
{
-eautomatic
}
or
\ccode
{
--equivalence=automatic
}
, then it approximates
the termination behavior of operations with some sufficient criteria.
If CurryCheck can prove that both operations are terminating,
it invokes the equivalence check for terminating operations as described above.
Instead of annotating the property name to use more efficient equivalence
tests for terminating operations, one can also ask CurryCheck
to analyze the operations in order to safely approximate
termination or productivity properties.
For this purpose, one can call CurryCheck with the option
\ccode
{
--equivalence=
$
equiv
$}
or
\ccode
{
-e
$
equiv
$}
.
The parameter
$
equiv
$
determines the mode for equivalence checking
which must have one of the following values (or a prefix of them):
%
\begin{description}
\item
[\code{manual}:]
This is the default mode. In this mode, all equivalence tests
are executed with first technique described above, unless
the name of the test has the suffix
\code
{
'TERMINATE
}
.
\item
[\code{autoselect}:]
This mode automatically selects the improved transformation
for terminating operations by a program analysis, i.e.,
if it can be proved that both operations are terminating, then
the equivalence test for terminating operations is used.
It is also used when the name of the test has the suffix
\code
{
'TERMINATE
}
.
\item
[\code{safe}:]
This mode analyzes the productivity behavior of operations.
If it can be proved that both operations are terminating
or the test name has the suffix
\code
{
'TERMINATE
}
, then
the more efficient equivalence test for terminating operations is used.
If it can be proved that both operations are productive
or the test name has the suffix
\code
{
'PRODUCTIVE
}
, then
the first general test technique is used.
Otherwise, the equivalence property is
\emph
{
not
}
tested.
Thus, this mode is useful if one wants to ensure that all
equivalence tests always terminate (provided that the additional
user annotations are correct).
\end{description}
\subsection
{
Checking Usage of Specific Operations
}
...
...
examples/equivalent_operations/Ints12.curry
View file @
58c70546
...
...
@@ -10,6 +10,5 @@ ints1 n = n : ints1 (n+1)
ints2 :: Int -> [Int]
ints2 n = n : ints2 (n+2)
--
F
alsified by 47th test:
--
This property will be f
alsified by
the
47th test:
ints1_equiv_ints2 = ints1 <=> ints2
src/CC/Options.curry
View file @
58c70546
...
...
@@ -51,7 +51,7 @@ defaultOptions = Options
}
--- Options for equivalence tests.
data EquivOption = Safe | Auto
matic
| Manual
data EquivOption = Safe | Auto
select
| Manual
deriving Eq
-- Definition of actual command line options.
...
...
@@ -77,7 +77,7 @@ options =
"type for defaulting polymorphic tests:\nBool | Int | Char | Ordering (default)"
, Option "e" ["equivalence"]
(ReqArg checkEquivOption "<e>")
"option for equivalence tests:\nsafe | auto
matic
| manual (default)"
"option for equivalence tests:\nsafe | auto
select
| manual (default)"
, Option "t" ["time"] (NoArg (\opts -> opts { optTime = True }))
"show run time for executing each property test"
, Option "" ["nosource"]
...
...
@@ -118,9 +118,9 @@ options =
else error "Illegal default type (try `-h' for help)"
checkEquivOption s opts
| ls `isPrefixOf` "SAFE" = opts { optEquiv = Safe }
| ls `isPrefixOf` "AUTO
MATIC
" = opts { optEquiv = Auto
matic
}
| ls `isPrefixOf` "MANUAL" = opts { optEquiv = Manual
}
| ls `isPrefixOf` "SAFE"
= opts { optEquiv = Safe }
| ls `isPrefixOf` "AUTO
SELECT
" = opts { optEquiv = Auto
select
}
| ls `isPrefixOf` "MANUAL"
= opts { optEquiv = Manual }
| otherwise = error "Illegal equivalence option (try `-h' for help)"
where ls = map toUpper s
...
...
src/CurryCheck.curry
View file @
58c70546
...
...
@@ -55,7 +55,7 @@ ccBanner :: String
ccBanner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText = "CurryCheck: a tool for testing Curry programs (Version " ++
packageVersion ++ " of 1
0
/02/2018)"
packageVersion ++ " of 1
1
/02/2018)"
bannerLine = take (length bannerText) (repeat '-')
-- Help text
...
...
@@ -1056,7 +1056,7 @@ ctypedecl2ftypedecl (CType qtc _ tvars consdecls _) =
genMainTestModule :: Options -> String -> [TestModule] -> IO [Test]
genMainTestModule opts mainmod testmods = do
let equivtestops = nub (concatMap equivTestOps (concatMap propTests testmods))
terminfos <- if optEquiv opts == Auto
matic
terminfos <- if optEquiv opts == Auto
select
then getTerminationInfos opts (nub (map fst equivtestops))
else return (const False)
prodinfos <- if optEquiv opts == Safe
...
...
Write
Preview
Supports
Markdown
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