Commit b5d035e8 authored by Michael Hanus's avatar Michael Hanus
Browse files

Manuals for tools extended

parent 09927427
......@@ -19,7 +19,7 @@ like regular expressions, format specifications (\ccode{printf}),
HTML and XML code.
\item[Sequential rules:]
If this feature is used, all rules in a Curry module are
interpreted as sequential, i.e., a rule is only applied
interpreted as sequential, i.e., a rule is applied only
if all previous rules defining the same operation are not applicable.
The idea of sequential rules are described in \cite{AntoyHanus14}.
\item[Default rules:]
......@@ -29,7 +29,7 @@ This provides a similar power than sequential rules
but with a better operational behavior.
The idea of default rules are described in \cite{AntoyHanus16PADL}.
\end{description}
%
The preprocessor is an executable named \ccode{currypp},
which is stored in the directory \code{\cyshome/bin}.
In order to apply the preprocessor when loading a Curry source
......@@ -85,26 +85,247 @@ supported foreign languages.
\subsubsection{Regular Expressions}
TODO
In order to match strings against regular expressions, i.e.,
to check whether a string is contained in the language
generated by a regular expression, one can specify
regular expression similar to POSIX. The foreign regular
expression code must be marked by \ccode{regexp}.
Since this code is transformed into operations of the \CYS library
\code{RegExp}, this library must be imported.
For instance, the following module defines a predicate
to check whether a string is a valid identifier:
\begin{curry}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
import RegExp
isID :: String -> Bool
isID s = s ``regex [a-zA-Z][a-zA-Z0-9_']*''
\end{curry}
\subsubsection{Format Specifications}
TODO
In order to format numerical and other data as strings,
one can specify the desired format with foreign code marked by
\ccode{format}. In this case, one can write a format specification,
similarly to the \code{printf} statement of C,
followed by a comma-separated list of arguments.
This format specification is transformed into operations
of the \CYS library \code{Format} so that it must be imported.
For instance, the following program defines an operation
that formats a string, an integer (with leading sign and zeros),
and a float with leading sign and precision 3:
\begin{currynomath}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
import Format
showSIF :: String -> Int -> Float -> String
showSIF s i f = ``format "Name: %s | %+.5i | %+6.3f",s,i,f''
main = putStrLn $ showSIF "Curry" 42 3.14159
\end{currynomath} % $
Thus, the execution of \code{main} will print the line
\begin{curry}
Name: Curry | +00042 | +3.142
\end{curry}
Instead of \ccode{format}, one can also write a format specification
with \code{printf}. In this case, the formatted string is
printed with \code{putStr}. Hence, we can rewrite our previous definitions
as follows:
\begin{curry}
showSIF :: String -> Int -> Float -> IO ()
showSIF s i f = ``printf "Name: %s | %+.5i | %+6.3f\n",s,i,f''
main = showSIF "Curry" 42 3.14159
\end{curry}
\subsubsection{HTML Code}
TODO
The foreign language tag \ccode{html} introduces a notation
for HTML expressions (see \CYS library \code{HTML})
with the standard HTML syntax extended by a layout rule
so that closing tags can be omitted.
In order to include strings computed by Curry expressions
into these HTML syntax, these Curry expressions must be enclosed
in curly brackets.
The following example program shows its use:
\begin{curry}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
import HTML
htmlPage :: String -> [HtmlExp]
htmlPage name = ``html
<html>
<head>
<title>Simple Test
<body>
<h1>Hello {name}!</h1>
<p>
Bye!
<p>Bye!
<h2>{reverse name}
Bye!''
\end{curry}
%
If a Curry expression computes an HTML expression,
i.e., it is of type \code{HtmlExp} instead of \code{String},
it can be integrated into the HTML syntax by double curly brackets.
The following simple example, taken from \cite{Hanus01PADL},
shows the use of this feature:
\begin{currynomath}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
import HTML
main :: IO HtmlForm
main = return $ form "Question" $
``html
Enter a string: {{textfield tref ""}}
<hr>
{{button "Reverse string" revhandler}}
{{button "Duplicate string" duphandler}}''
where
tref free
revhandler env = return $ form "Answer"
``html <h1>Reversed input: {reverse (env tref)}''
duphandler env = return $ form "Answer"
``html
<h1>
Duplicated input:
{env tref ++ env tref}''
\end{currynomath}
\subsubsection{XML Expressions}
TODO
The foreign language tag \ccode{xml} introduces a notation
for XML expressions (see \CYS library \code{XML}).
The syntax is similar to the language tag \ccode{html},
i.e., the use of the layout rule avoids closing tags
and Curry expressions evaluating to strings (\code{String})
and XML expressions (\code{XmlExp}) can be included by enclosing
them in curly and double curly brackets, respectively.
The following example program shows its use:
\begin{currynomath}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=foreigncode #-}
import HTML
import XML
main :: IO ()
main = putStrLn $ showXmlDoc $ head ``xml
<contact>
<entry>
<phone>+49-431-8807271
<name>Hanus
<first>Michael
<email>mh@informatik.uni-kiel.de
<email>hanus@email.uni-kiel.de
<entry>
<name>Smith
<first>Bill
<phone>+1-987-742-9388
''
\end{currynomath}
\subsection{Sequential Rules}
TODO
If the Curry preprocessor is called with the option
\ccode{seqrules}, then all rules in the Curry module are
interpreted in a sequential manner, i.e., a rule is applied only
if all previous rules defining the same operation are not applicable,
either because the left-hand side's pattern does not match
or the condition is not satisfiable.
The idea and detailed semantics of
sequential rules are described in \cite{AntoyHanus14}.
Sequential rules are useful and preferable over
rules with multiple guards if the patterns are non-trivial
(e.g., functional patterns) or the condition involve complex
constraints.
As a simple example, the following module defines
a lookup operation in association lists by a functional pattern.
Due to the sequential rule strategy,
the second rule is applied only if there is no appropriate
key in the association list:
%
\begin{curry}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=seqrules #-}
mlookup key (_ ++ [(key,value)] ++ _) = Just value
mlookup _ _ = Nothing
\end{curry}
\subsection{Default Rules}
TODO
An alternative to sequential rules are default rules, i.e.,
these two options cannot be simultaneously used.
Default rules are activated by the preprocessor option
\ccode{defaultrules}.
In this case, one can add to each operation a default rule.
A default rule for a function $f$ is defined as a rule
defining the operation \ccode{$f$'default} (this mechanism
avoids any language extension for default rules).
A default rule is applied only if no ``standard'' rule is
applicable, either because the left-hand sides' pattern do not match
or the conditions are not satisfiable.
Default rules are preferable over the sequential rule selection
strategy since they have a better operational behavior.
This is due to the fact that the test for the application
of default rules is done with the same (sometimes optimal)
strategy than the selection of standard rules.
Moreover, default rules provide a similar power than sequential rules,
i.e., they can be applied if the standard rules have
complex (functional) patterns or complex conditions.
As a simple example, we show the implementation of the
previous example for sequential rules with a default rule:
%
\begin{curry}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=defaultrules #-}
mlookup key (_ ++ [(key,value)] ++ _) = Just value
mlookup'default _ _ = Nothing
\end{curry}
%
Default rules are often a good replacement for ``negation as failure''
used in logic programming.
For instance, the following program defines a solution
to the $n$-queens puzzle, where the default rule is useful
since it is easier to characterize the unsafe positions
of the queens on the chessboard (see the first rule of \code{safe}):
%
\begin{curry}
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=defaultrules #-}
import Combinatorial(permute)
import Integer(abs)
-- A placement is safe if two queens are not in a same diagonal:
safe (_++[x]++ys++[z]++_) | abs (x-z) == length ys + 1 = failed
safe'default xs = xs
-- A solution to the n-queens puzzle is a safe permutation:
queens :: Int -> [Int]
queens n = safe (permute [1..n])
\end{curry}
% LocalWords: preprocessor
......@@ -61,3 +61,11 @@ test20 = assertTrue "Email1" (isEmail "pakcs@curry-language.org")
test21 = assertTrue "Email2" (not (isEmail "pa%kcs@curry-language.org"))
isID :: String -> Bool
isID s = s ``regex [a-zA-Z][a-zA-Z0-9_']*''
test30 = assertTrue "ID1" (isID "ab_4'aux")
test31 = assertTrue "ID2" (not (isID "4ab"))
This directory contains some documention for the Curry optimizer:
manual.tex:
A short description to be included in the main manual of the Curry system.
\section{Optimization of Curry Programs}
After the invocation of the Curry front end,
which parses a Curry program and translates it into the intermediate FlatCurry
representation, \CYS applies a transformation
to optimize Boolean equalities occurring in the Curry program.
The ideas and details of this optimization are described
in \cite{AntoyHanus15LOPSTR}.
Therefore, we sketch only some basic ideas and options
to influence this optimization.
Consider the following definition of the operation \code{last}
to extract the last element in list:
%
\begin{curry}
last xs | xs == _++[x]
= x
where x free
\end{curry}
%
In order to evaluate the condition \ccode{xs == \us{}++[x]},
the Boolean equality is evaluated to \code{True} or \code{False}
by instantiating the free variables \code{\us} and \code{x}.
However, since we know that a condition must be evaluated to
\code{True} only and all evaluations to \code{False} can be ignored,
we can use the constrained equality to obtain a more efficient program:
%
\begin{curry}
last xs | xs =:= _++[x]
= x
where x free
\end{curry}
%
Since the selection of the appropriate equality operator
is not obvious and might be tedious, \CYS encourages
programmers to use only the Boolean equality operator \ccode{==}
in programs.
The constraint equality operator \ccode{=:=} can be considered
as an optimization of \ccode{==} if it is ensured that only
positive results are required, e.g., in conditions of program rules.
To support this programming style, \CYS has a built-in optimization phase
on FlatCurry files. For this purpose, the optimizer analyzes
the FlatCurry programs for occurrences of \ccode{==}
and replaces them by \ccode{=:=} whenever the result \code{False}
is not required.
The usage of the optimizer can be influenced by setting
the property flag \code{bindingoptimization} in the
configuration file \code{\curryrc}.
The following values are recognized for this flag:
\begin{description}
\item[\code{no}:] Do not apply this transformation.
\item[\code{fast}:] This is the default value.
The transformation is based on pre-computed values for
the prelude operations in order to decide whether the
value \code{False} is not required as a result of a Boolean equality.
Hence, the transformation can be efficiently performed
without any complex analysis.
\item[\code{full}:] Perform a complete ``required values'' analysis
of the program (see \cite{AntoyHanus15LOPSTR})
and use this information to optimize programs.
In most cases, this does not yield better results so that
the \code{fast} mode is sufficient.
\end{description}
%
Hence, to turn off this optimization, one can either modify
the flag \code{bindingoptimization} in the
configuration file \code{\curryrc} or dynamically pass this change
to the invocation of \CYS by
\begin{quote}
\ldots{} \code{-Dbindingoptimization=no} \ldots
\end{quote}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment