69 research outputs found

    Compiling ER Specifications into Declarative Programs

    Full text link
    This paper proposes an environment to support high-level database programming in a declarative programming language. In order to ensure safe database updates, all access and update operations related to the database are generated from high-level descriptions in the entity- relationship (ER) model. We propose a representation of ER diagrams in the declarative language Curry so that they can be constructed by various tools and then translated into this representation. Furthermore, we have implemented a compiler from this representation into a Curry program that provides access and update operations based on a high-level API for database programming.Comment: Paper presented at the 17th Workshop on Logic-based Methods in Programming Environments (WLPE2007

    Implementing Functional Logic Programs by Translation into Purely Functional Programs

    Get PDF
    This work examines a transformation scheme from functional logic programs to purely functional programs both formally and experimentally

    Structure and Properties of Traces for Functional Programs

    Get PDF
    The tracer Hat records in a detailed trace the computation of a program written in the lazy functional language Haskell. The trace can then be viewed in various ways to support program comprehension and debugging. The trace was named the augmented redex trail. Its structure was inspired by standard graph rewriting implementations of functional languages. Here we describe a model of the trace that captures its essential properties and allows formal reasoning. The trace is a graph constructed by graph rewriting but goes beyond simple term graphs. Although the trace is a graph whose structure is independent of any rewriting strategy, we define the trace inductively, thus giving us a powerful method for proving its properties

    Non-linear Pattern Matching with Backtracking for Non-free Data Types

    Full text link
    Non-free data types are data types whose data have no canonical forms. For example, multisets are non-free data types because the multiset {a,b,b}\{a,b,b\} has two other equivalent but literally different forms {b,a,b}\{b,a,b\} and {b,b,a}\{b,b,a\}. Pattern matching is known to provide a handy tool set to treat such data types. Although many studies on pattern matching and implementations for practical programming languages have been proposed so far, we observe that none of these studies satisfy all the criteria of practical pattern matching, which are as follows: i) efficiency of the backtracking algorithm for non-linear patterns, ii) extensibility of matching process, and iii) polymorphism in patterns. This paper aims to design a new pattern-matching-oriented programming language that satisfies all the above three criteria. The proposed language features clean Scheme-like syntax and efficient and extensible pattern matching semantics. This programming language is especially useful for the processing of complex non-free data types that not only include multisets and sets but also graphs and symbolic mathematical expressions. We discuss the importance of our criteria of practical pattern matching and how our language design naturally arises from the criteria. The proposed language has been already implemented and open-sourced as the Egison programming language

    From Boolean Equalities to Constraints

    Get PDF
    Although functional as well as logic languages use equality to discriminate between logically different cases, the operational meaning of equality is different in such languages. Functional languages reduce equational expressions to their Boolean values, True or False, logic languages use unification to check the validity only and fail otherwise. Consequently, the language Curry, which amalgamates functional and logic programming features, offers two kinds of equational expressions so that the programmer has to distinguish between these uses. We show that this distinction can be avoided by providing an analysis and transformation method that automatically selects the appropriate operation. Without this distinction in source programs, the language design can be simplified and the execution of programs can be optimized. As a consequence, we show that one kind of equational expressions is sufficient and unification is nothing else than an optimization of Boolean equality

    Combining Static and Dynamic Contract Checking for Curry

    Full text link
    Static type systems are usually not sufficient to express all requirements on function calls. Hence, contracts with pre- and postconditions can be used to express more complex constraints on operations. Contracts can be checked at run time to ensure that operations are only invoked with reasonable arguments and return intended results. Although such dynamic contract checking provides more reliable program execution, it requires execution time and could lead to program crashes that might be detected with more advanced methods at compile time. To improve this situation for declarative languages, we present an approach to combine static and dynamic contract checking for the functional logic language Curry. Based on a formal model of contract checking for functional logic programming, we propose an automatic method to verify contracts at compile time. If a contract is successfully verified, dynamic checking of it can be omitted. This method decreases execution time without degrading reliable program execution. In the best case, when all contracts are statically verified, it provides trust in the software since crashes due to contract violations cannot occur during program execution.Comment: Pre-proceedings paper presented at the 27th International Symposium on Logic-Based Program Synthesis and Transformation (LOPSTR 2017), Namur, Belgium, 10-12 October 2017 (arXiv:1708.07854

    Delta Debugging Type Errors with a Blackbox Compiler

    Get PDF
    Debugging type errors is a necessary process that programmers, both novices and experts alike, face when using statically typed functional programming languages. All compilers often report the location of a type error inaccurately. This problem has been a subject of research for over thirty years. We present a new method for locating type errors: We apply the Isolating Delta Debugging algorithm coupled with a blackbox compiler. We evaluate our implementation for Haskell by comparing it with the output of the Glasgow Haskell Compiler; overall we obtain positive results in favour of our method of type error debugging

    Lightweight Computation Tree Tracing for Lazy Functional Languages

    Get PDF
    A computation tree of a program execution describes computations of functions and their dependencies. A computation tree describes how a program works and is at the heart of algorithmic debugging. To generate a computation tree, existing algorithmic debuggers either use a complex implementation or yield a less informative approximation. We present a method for lazy functional languages that requires only a simple tracing library to generate a detailed computation tree. With our algorithmic debugger a programmer can debug any Haskell program by only importing our library and annotating suspected functions

    Compiling a Functional Logic Language: The Fair Scheme

    Full text link
    Abstract. We present a compilation scheme for a functional logic programming language. The input program to our compiler is a constructor-based graph rewrit-ing system in a non-confluent, but well-behaved class. This input is an interme-diate representation of a functional logic program in a language such as Curry or T OY. The output program from our compiler consists of three procedures that make recursive calls and execute both rewrite and pull-tab steps. This output is an intermediate representation that is easy to encode in any number of programming languages. Our design evolves the Basic Scheme of Antoy and Peters by removing the “left bias ” that prevents obtaining results of some computations—a behavior related to the order of evaluation, which is counter to declarative programming. The benefits of this evolution are not only the strong completeness of computa-tions, but also the provability of non-trivial properties of these computations. We rigorously describe the compiler design and prove some of its properties. To state and prove these properties, we introduce novel definitions of “need ” and “fail-ure. ” For non-confluent constructor-based rewriting systems these concepts are more appropriate than the classic definition of need of Huet and Levy
    corecore