Functional Notation and Lazy Evaluation in Ciao

Similar documents
Functional Notation and Lazy Evaluation in Ciao

A Syntactic Approach to Combining Functional Notation, Lazy Evaluation, and Higher-Order in LP Systems

Annotation Algorithms for Unrestricted Independent And-Parallelism in Logic Programs

Towards a High-Level Implementation of Flexible Parallelism Primitives for Symbolic Languages

The Prolog to Mercury transition guide

Computational Logic: (Constraint) Logic Programming Theory, practice, and implementation

Multi-paradigm Declarative Languages

Shell CSCE 314 TAMU. Haskell Functions

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

Scope, Functions, and Storage Management

An overview of Ciao and its design philosophy

An overview of Ciao and its design philosophy

arxiv: v1 [cs.pl] 27 Feb 2011

Lecture 5: Lazy Evaluation and Infinite Data Structures

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

CSCE 314 Programming Languages

Chapter 9: Constraint Logic Programming

Curry. An Integrated Functional Logic Language. Version January 13, Michael Hanus 1 [editor] Additional Contributors:

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Basics

This lecture covers: Prolog s execution strategy explained more precisely. Revision of the elementary Prolog data types

3. Functional Programming. Oscar Nierstrasz

documenting programs, including: A traditional, command line interactive top level.

CS 320: Concepts of Programming Languages

Continuations and Continuation-Passing Style

Functional Logic Programming Language Curry

COMP 3141 Software System Design and Implementation

Imperative languages

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Chapter 15. Functional Programming Languages

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

INTRODUCTION TO HASKELL

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

Agent Programming in Ciao Prolog

Multi-paradigm Declarative Languages

Implementação de Linguagens 2016/2017

CPS 506 Comparative Programming Languages. Programming Language Paradigm

User s Functions in Standard Prolog

Functional Programming

Topic 5: Examples and higher-order functions

Declaring Numbers. Bernd Braßel, Frank Huch and Sebastian Fischer. Department of Computer Science, University of Kiel, Germany

The Metalanguage λprolog and Its Implementation

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Functional Programming. Big Picture. Design of Programming Languages

Lambda Calculus see notes on Lambda Calculus

Lecture 19: Functions, Types and Data Structures in Haskell

COP4020 Programming Assignment 1 - Spring 2011

Lambda Calculus.

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Functional Programming and Haskell

Runtime support for region-based memory management in Mercury

Functional Programming in C++

JVM ByteCode Interpreter

Types and Type Inference

Comp 411 Principles of Programming Languages Lecture 7 Meta-interpreters. Corky Cartwright January 26, 2018

CSE 3302 Programming Languages Lecture 8: Functional Programming

Sometimes it s good to be lazy

CS 457/557: Functional Languages

facultad de informatica universidad politecnica de madrid

Lecture 8: Summary of Haskell course + Type Level Programming

CS 242. Fundamentals. Reading: See last slide

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

Adding Constraint Handling Rules to Curry Extended Abstract

Functional Programming

Principles of Programming Languages, Appendix

Option Values, Arrays, Sequences, and Lazy Evaluation

Foundations. Yu Zhang. Acknowledgement: modified from Stanford CS242

An Explicit Continuation Evaluator for Scheme

Functional Programming Languages (FPL)

To figure this out we need a more precise understanding of how ML works

Functional Logic Programming. Kristjan Vedel

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Background Operators (1E) Young Won Lim 7/7/18

Parsing Scheme (+ (* 2 3) 1) * 1

The PCAT Programming Language Reference Manual

An introduction introduction to functional functional programming programming using usin Haskell

Introduction to the Lambda Calculus

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

Part I Logic programming paradigm

Organization of Programming Languages CS3200/5200N. Lecture 11

What are Operators? - 1. Operators. What are Operators? - 2. Properties. » Position» Precedence class» associativity. » x + y * z. » +(x, *(y, z)).

Tail Recursion. ;; a recursive program for factorial (define fact (lambda (m) ;; m is non-negative (if (= m 0) 1 (* m (fact (- m 1))))))

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

COMP 1130 Lambda Calculus. based on slides by Jeff Foster, U Maryland

LECTURE 16. Functional Programming

Chapter 15. Functional Programming Languages ISBN

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

1.3. Conditional expressions To express case distinctions like

Lexical vs. Dynamic Scope

4.2 Variations on a Scheme -- Lazy Evaluation

Functional Programming Lecture 1: Introduction

Topic B: Backtracking and Lists

CSc 372 Comparative Programming Languages

Programming Paradigms

Fundamentals and lambda calculus

Declarative Multi-paradigm Programming

Y-Combinator. Contents. 1 Introduction. Avi Hayoun, Hodai Goldman and Lior Zur-Lotan. November 24, Terms recap. 1.2 Y-Combinator notes

Artificial Intelligence Course Sharif University of Technology

Transcription:

Slide 0 Functional Notation and Lazy Evaluation in Ciao Amadeo Casas 1 Daniel Cabeza 2 Manuel Hermenegildo 1,2 amadeo@cs.unm.edu, {dcabeza, herme }@fi.upm.es 1 Depts. of Comp. Science and Electr. and Comp. Eng., Univ. of New Mexico, Albuquerque, NM, USA. 2 School of Computer Science, T. U. Madrid (UPM), Madrid, Spain CLIP Group

Introduction Slide 1 Logic Programming offers a number of features, such as nondeterminism and partially instantiated data structures, that give it expressive power beyond that of functional programming. Functional Programming provides syntactic convenience, by having a syntactically designated output argument. Functional Programming also provides the ability to deal with infinite data structures by means of lazy evaluation. We present a design for an extensive functional layer for logic programs and its implementation in the Ciao system.

Why this is new Slide 2 Adding functional features to LP systems is clearly not new: Work by Bella, Levi, et al. Naish: equations in NU-Prolog. A good number of systems which integrate functions into some form of L.P.: Oz, Mercury, HAL, Lambda-Prolog,... Or perform a full integration of Functional and Logic Programming (e.g., Curry). Our proposal and its implementation has peculiarities which make it interesting: The system supports ISO-Prolog. The Language is extensible (and restrictable). Functional features added at the source (Prolog) level. Using Ciao packages (no compiler or machinery modification). Functions retain the power of predicates (it s just notation).

Slide 3 Functional Notation in Ciao (I) Function applications: Any term preceded by the /1 operator is a function application: write( arg(1, T)). arg(1, T, A), write(a). The next declaration avoids the need to use the /1 operator: :- function arg/2. write(arg(1, T)). It is possible to use a predicate argument other than the last as the return argument: :- fun return functor(,, ). functor(, f, 2). The following declaration combines the previous two: :- function functor(,, ). :- fun return functor(,, ). :- function functor/2.

Functional Notation in Ciao (II) Slide 4 Predefined evaluable functors: several functors are evaluable by default: All the functors understood by is/2. Can be disabled by a declaration: :- function arith(false). % reverted by using true. Functors used for disjunctive and conditional expressions: (Cond1? V1 (Cond2? V2 V3)). Functional definitions: fact(0) := 1. % Using body guards fact(n) := N * fact(--n) :- N > 0. fac(n) := N = 0? 1 % using conditional expressions N > 0? N * fac(--n). The translation of functional clauses defining recursive predicates maintains the tail recursion of the equivalent predicate.

Functional Notation in Ciao (III) Slide 5 Quoting functors: functors can be prevented from being evaluated: pair(a,b) := ˆ(A-B). Scoping: function applications evaluated in the scope of the outer execution. If they should be evaluated in the inner scope, the goal containing the function application needs to be escaped with the (ˆˆ)/1 operator: findall(x, (d(y), ˆˆ(X = f(y)+1)), L). Laziness: an expression is not evaluated as soon as it is assigned, but rather when the evaluator is forced to produce the value of the expression: :- lazy function nums_from/1. nums_from(x) := [X nums_from(x+1)].

Functional Notation in Ciao (IV) Slide 6 Definition of real functions: functions not forced to provide a single solution for their result. In order to declare a function as a real function: :- funct name/n. which adds pruning operators and Ciao assertions to add restrictions as determinacy and modedness. Functional notation really useful to write regular types in a very compact way: color := red blue green. list := [] [ _ list]. list_of(t) := [] [ T list_of(t)].

Example of Functional Notation in Ciao Slide 7 :- function(arith(false)). der(x) := 1. der(c) := 0 :- number(c). der(a + B) := der(a) + der(b). der(c * A) := C * der(a) :- number(c). der(x ** N) := N * x ** (N - 1) :- integer(n), N > 0. der(x, 1). der(c, 0) :- number(c). der(a + B, X + Y) :- der(a, X), der(b, Y). der(c * A, C * X) :- number(c), der(a, X). der(x ** N, N * x ** N1) :- integer(n), N > 0, N1 is N - 1.

Higher-Order Slide 8 Not topic of this paper, but combines well with these syntactic extensions. Adding functions to higher-order in Ciao: Predicate abstraction Function abstraction { (X,Y) :- p(x,z), q(z,y)} { (X) := q( p(x))} Predicate application Function application..., P(X,Y),......, Y = P(X),... The integration is at the predicate level.

Implementation Details Slide 9 Functional features provided by two Ciao packages. Packages in Ciao are libraries which define extensions to the language. Packages are based in the redesigning of the traditional term expansions and operator definitions to make them more well-behaved and local to the module. Two packages: one for the bare function features without lazy evaluation, and an additional one to provide the lazy evaluation features. Basic functional features are translated using the well-known technique of adding a goal for each function application.

Lazy Functions Implementation Slide 10 Translation of a lazy function into a predicate is done in two steps: First, the function is converted into a predicate by the bare functions package. The predicate is transformed to suspend its execution until the value of the output variable is needed, by the use of the freeze/2 control primitive. The translation will rename the original predicate to an internal name and add a bridge predicate with the original name which invokes the internal predicate through a call to freeze/1.

Example of Lazy Functions Slide 11 :- lazy function fiblist/0. fiblist := [0, 1 zipwith(add, FibL, tail(fibl))] :- FibL = fiblist. :- lazy fiblist/1. fiblist([0, 1 Rest]) :- fiblist(fibl), tail(fibl, T), zipwith(add, FibL, T, Rest). fiblist(x) :- freeze(x, fiblist_$$lazy$$ (X)). fiblist_$$lazy$$ ([0, 1 Rest]) :- fiblist(fibl), tail(fibl, T), zipwith(add, FibL, T, Rest).

Performance Measurements (I) Slide 12 Lazy Evaluation Eager Evaluation List Time Heap Time Heap 10 elements 0.030 1503.2 0.002 491.2 100 elements 0.276 10863.2 0.016 1211.2 1000 elements 3.584 104463.0 0.149 8411.2 2000 elements 6.105 208463.2 0.297 16411.2 5000 elements 17.836 520463.0 0.749 40411.2 10000 elements 33.698 1040463.0 1.277 80411.2 Table 1: Performance for nat/2 (time in ms. and heap sizes in bytes). :- function nat/1. nat(n) := take(n, nums_from(0)). :- lazy function nums_from/1. nums_from(x) := [X nums_from(x+1)].

Performance Measurements (II) Slide 13 Lazy Evaluation Eager Evaluation List Time Heap Time Heap 10 elements 0.091 3680.0 0.032 1640.0 100 elements 0.946 37420.0 0.322 17090.0 1000 elements 13.303 459420.0 5.032 253330.0 5000 elements 58.369 2525990.0 31.291 1600530.0 15000 elements 229.756 8273340.0 107.193 5436780.0 20000 elements 311.833 11344800.0 146.160 7395100.0 Table 2: Performance for qsort/2 (time in ms. and heap sizes in bytes). :- lazy function qsort/1. qsort(x) := qsort_(x, []). :- lazy function qsort_/2. qsort_([], Acc) := Acc. qsort_([], Acc) := Acc. qsort_([x T], Acc) := qsort_(s, [X qsort_(g, Acc)]) :- (S, G) = partition(t, X). :- lazy function partition/3. partition([], _) := ([], []). partition([x T], Y) := (S, [X G]) :- Y < X,!, (S,G) = partition(t, Y). partition([x T], Y) := ([X S], G) :-!, (S,G) = partition(t, Y).

Lazy Evaluation vs. Eager Evaluation Slide 14 :- module(module1, [test/1], [functions, lazy, hiord, actmods]). :- use_module(library( act mod s/w ebb ase d_l oc ate )). :- use_active_module(mo dul e2, [squares/2]). :- function takewhile/2. takewhile(p, [H T]) := P(H)? [H takewhile(p, T)] []. :- function test/0. test := takewhile( { (X) := X < 10000 }, squares). :- module(module2, [squares/1], [functions, lazy, hiord]). :- lazy function squares/0. squares := map_lazy(take(1000000, nums_from(0)), { (X) := X * X }). :- lazy function map_lazy/2. map_lazy([], _) := []. map_lazy([x Xs], P) := [ P(X) map_lazy(xs, P)]. :- function take/2. take(0, _) := []. take(x, [H T]) := [H take(x-1, T)] :- X > 0. :- lazy function nums_from/1. nums_from(x) := [X nums_from(x+1)].

Conclusions Slide 15 We have presented a functional extension of Prolog, which includes the possibility of evaluating functions lazily. The proposed approach has been implemented in Ciao and is used now throughout the libraries and other system code as well as in a number of applications written by the users of the system. The performance of the package has been tested with several examples. As expected, evaluating functions lazily implies some time and memory overhead with respect to eager evaluation. The main advantage of lazy evaluation is to make it easy to work with infinite data structures in the manner that is familiar to functional programmers.