DSDCurry: A tool for Declarative Software Development

DSDCurry is a transformation tool which generates from a Curry module containing pre/postconditions and specifications of operations a new Curry module where assertions are added to check these pre/postconditions and specifications.

The ideas of this tool and declarative software development with specifications and pre/postconditions in Curry are described in this paper:

Sergio Antoy, Michael Hanus: Contracts and Specifications for Functional Logic Programming, Proc. of the 14th International Symposium on Practical Aspects of Declarative Languages (PADL 2012), Springer LNCS 7149, pp. 33-47, 2012

How to use the tool:
After installing the tool with
> cpm install dsdcurry
(which installs the binary dsdcurry in ~/.cpm/bin), you can use it as follows:
If Mod.curry contains your Curry module with pre/postconditions, execute
> dsdcurry mod
to generate new module ModC.curry where assertions are added.
Load the new module into PAKCS and run it by
> pakcs :load ModC
You can also transform and load the module into PAKCS in one step by
> dsdcurry -r Mod

Assumptions:

it will be considered as "to be implemented", i.e., an implementation will be generated from a specification or postcondition (see below). Providing such an "unknown" definition might be necessary in larger programs where one wants to apply a function without having its final implementation.

Command-line arguments:
Usage: dsdcurry [-s|-f|-l|-e|-pcs|-r|-d]
-s : generate strict assertions (default) -l : generate lazy assertions -f : generate lazy enforceable assertions -e : encapsulate nondeterminism of assertions (see examples/ndassertion.curry) -pcs : take single result of funcs generated from postconditions -r : load the transformed program into PAKCS -d : show assertion results during execution (with -r)

Examples:

See programs in the directory examples

Known problems:
- Sometimes the type signatures of the generated functions are too general if the type signature of pre/postconditions are more general than the type of the generated function that is required by the later use of the function.
Solution: add restrictive type signature to pre/postconditions in your program or add a type signature for the function with a body f = unknown
- Strict assertions make operations stricter, thus, changing the run-time behavior.
Solution: use lazy assertions (option -l), but this has the risk that some assertions will never be checked
Better solution: use enforceable assertions (option -f), i.e., evaluate assertion lazily but enforce their evaluation at the end by evaluating the main expression e by enforce e (or enforceIO e if e is an I/O action).