0% found this document useful (0 votes)
38 views

Lazy Coding PPL

This document discusses concepts related to functional programming languages including: - Strict vs non-strict (lazy) evaluation and how it affects evaluation order and correctness - Lazy evaluation techniques like memoization that provide benefits of both normal and applicative order evaluation - Modeling I/O as streams to avoid side effects but streams do not work well for graphics or random file access - Logic programming uses Horn clauses and resolution to derive new statements by combining existing statements - Prolog is a logic programming language where clauses can be facts or rules and goals are queried - Prolog departs from pure logic in its ordering dependence and uses cuts and negation to implement control flow

Uploaded by

sajinss
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views

Lazy Coding PPL

This document discusses concepts related to functional programming languages including: - Strict vs non-strict (lazy) evaluation and how it affects evaluation order and correctness - Lazy evaluation techniques like memoization that provide benefits of both normal and applicative order evaluation - Modeling I/O as streams to avoid side effects but streams do not work well for graphics or random file access - Logic programming uses Horn clauses and resolution to derive new statements by combining existing statements - Prolog is a logic programming language where clauses can be facts or rules and goals are queried - Prolog departs from pure logic in its ordering dependence and uses cuts and negation to implement control flow

Uploaded by

sajinss
Copyright
© © All Rights Reserved
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 13

1.

STRICTNESS & LAZY EVALUATION


1.1. Evaluation order can have an effect
not only on execution speed, but on
program correctness as well.
1.2. A program that encounters error
under applicative-order evaluation may
terminate successfully under normal-order
evaluation.
1.3. A (side-effect-free) function is
said to be strict if it is undefined
(fails to terminate, or encounters an
error) when any of its arguments is
undefined.
1.4. A function is said to be nonstrict
if it does not impose this requirement
that is, if it is sometimes defined even
when one of its arguments is not.
1.5.
a) A language is said to be strict if
it is defined in such a way that
functions are always strict.
If a language always evaluates
expressions in applicative order,
then every function is guaranteed to
be strict, because whenever an
argument is undefined, its evaluation
will fail and so will the function to
which it is being passed.
b) A language is said to be nonstrict
if it permits the definition of
nonstrict functions.
a nonstrict language cannot use

applicative order; it must use normal


order to avoid evaluating unneeded
arguments.
1.6. LAZY EVALUATION
a) Lazy evaluation gives us the
advantage of normal-order evaluation
(not evaluating unneeded
subexpressions) while running within a
constant factor of the speed of
applicative-order evaluation for
expressions in which everything is
needed.
b) The trick is to tag every argument
internally with a memo that indicates
its value, if known. Any attempt to
evaluate the argument sets the value in
the memo as a side effect, or returns
the value (without recalculating it) if
it is already set.

c)

d) Applicative order
e) lazy normal-orderLazy evaluation is
used for all arguments in Miranda and

Haskell. It is available in Scheme


through explicit use of delay and force
f) PBM: in presence of side-effects. If
changed elsewhere. In scheme upto
pgmmer (use of delay enclosed by
force). NOT in Haskell Miranda as they
are PURE FUNCTIONAL (no side effects).
2. I/O STREAM & MONADS
2.1. I/O
a) A major source of side effects can
be found I/O. Read returns a different
value every time it is called, and
multiple calls to display , though they
never return a value, must occur in the
proper order if the program is to be
considered correct.
b) One way to avoid these side effects
is to model input and output as streams
unbounded-length lists whose elements
are generated lazily.
c) Eg.
Modelling I/O as streams
(define output (my-prog input) )
(define driver (lambda (s)
(if ( null? S ) '()
( display (car s) )
( driver (cdr s) )
)
)

)
(driver output)
Interactive Eg
( define squares (lambda (s)
( cons enter a number\n
( let ( (n (car s)) )
( if (eof-object? n) '()
(cons (* n n) (cons
#\newline (squares (cdr s) )
)
)
)
)
)
(define output (squares input) )
2.2. Unfortunately, while they
successfully encapsulate the imperative
nature of interaction at a terminal,
streams dont work very well for graphics
or random access to files.
3. LOGIC PROGRAMMING
3.1. Logic programming systems allow the
programmer to state a collection of
axioms from which theorems can be proven.
3.2. The user of a logic program states a
theorem, or goal, and the language

implementation attempts to find a


collection of axioms and inference steps
(including choices of values for
variables) that together imply the goal.
3.3. Axioms are written in a standard
form known as a Horn clause. A Horn
clause consists of a head, 2 or
consequent term H , and a body consisting
of terms B i :
H B 1 , B 2 , . . . , B n
3.4. In order to derive new statements, a
logic programming system combines
existing statements, canceling like
terms, through a process known as
resolution.
3.5. During resolution, free variables
may acquire values through unification
with expressions in matching terms.
4. PROLOG
4.1. Atoms in Prolog are similar to
symbols in Lisp.
4.2. The scope of every variable is
limited to the clause in which it
appears.
4.3. There are no declarations.
4.4. Variables can be instantiated to
(i.e., can take on) arbitrary values at
run time as a result of unification.
4.5. Structures consist of an atom called
the functor and a list of arguments
4.6. We use the termpredicate to refer
to the combination of a functor and an
arity (number of arguments).

4.7. The clauses in a Prolog database can


be classified as facts or rules, each of
which ends with a period.
a) A fact is a Horn clause without a
right-hand side.
b) A rule has a right-hand side:
4.8. It is also possible to write a
clause with an empty left-hand side. Such
a clause is called a query, or a goal.
4.9. Dependence on ordering is one of the
ways in which Prolog departs from pure
logic;
4.10. Resolution Principle - if C 1 and C
2 are Horn clauses and the head of C 1
matches one of the terms in the body of C
2 , then we can replace the term in C 2
with the body of C 1 .
4.11. The unification rules for Prolog
state that
a) A constant unifies only with itself.
b) Two structures unify if and only if
they have the same functor and the same
arity, and the corresponding arguments
unify recursively.
c) A variable unifies with anything. If
the other thing has a value, then the
variable is instantiated. If the other
thing is an uninstantiated variable,
then the two variables are associated
in such a way that if either is given a
value later, that value will be shared
by both.
4.12. Equality in Prolog is defined in

terms of unifiability.
4.13. It is possible for two variables to
be unified without instantiating them.
4.14. difference between functions and
Prolog predicates. The former have a
clear notion of inputs (arguments) and
outputs (results); the latter do not.
4.15. List : book
4.16. To handle arithmetic, Prolog
provides a built-in predicate, is , that
unifies its first argument with the
arithmetic value of its second argument:
4.17. Order of Evaluation EG: book.
Efficiency
4.18. Infinite Regression------book dgm
a) . In effect, the Prolog interpreter
gets lost in an infinite branch of the
search tree, and never discovers finite
branches to the right. We could avoid
this problem by exploring the tree in
breadth-first order, but that strategy
was rejected by Prologs designers
because of its expense: it can require
substantially more space, and does not
lend itself to a stack-based
implementation.
4.19. IMPERATIVE CONTROL FLOW
a) The cut is a zero-argument predicate
written as an exclamation point: ! .
member(X, [X | _]) :- !.
member(X, [_ | T]) :- member(X, T).
The cut on the right-hand side of the

first rule says that if X is the head


of L , we should not attempt to unify
member(X, L) with the left-hand side
of the second rule; the cut commits
us to the first rule.
****also for : Pruning unwanted
answers with the cut
****Using the cut for selection
****
In general, the cut can be used
whenever we want the effect of
if . . . then . . else :
statement :- condition, !,then_part.
statement :- else_part.
b) An alternative way to ensure that
member(X, L) succeeds no more than once
is to embed a use of \+ in the second
clause:
member(X, [X | _]).
member(X, [H | T]) :- X \= H,
member(X, T).
Here X \= H means X and H will not
unify; that is, \+(X = H) .
slightly less efficient: now the
interpreter will actually consider
the second rule, abandoning it only
after (re)unifying X with H and
reversing the sense of the test.
c) The fail predicate can be used in

conjunction with a generator to


implement a loop.
The idea of failure driven loops is to force Prolog to
backtrack until there are no more possibilities left.

Prolog automatically tries to backtrack when it fails. So,


adding a goal which always fails (such as the built in
predicate fail/0 which has no effect but to make Prolog
fail) at the end of a clause, will force Prolog to backtrack
over all the other goals in that clause until it has tried all
the possibilities

write_everybody_happy :- happy(X),
write(X),nl,
fail.
write_everybody_happy :- true.
If you consult this little program and the ask Prolog the
query write_everybody_happy, Prolog will look up in its database all
objects that make happy(X) true and will print them out on the screen.
So, if the database looked as follows
happy(harry).
happy(ron).
happy(hermione).
happy(hagrid).
Prolog would write on the screen
harry
ron
hermione
hagrid
yes

d)

LOOPING WITH AN UNBOUNDED GENERATOR

The following, for example, generates all of the natural


numbers:
natural(1).
natural(N) :- natural(M), N is M+1.
We can use this generator in conjunction with a test-cut
combination to iterate over the first n numbers:
my_loop(N) :- natural(I),
write(I), nl,
I = N, !.

% loop body (nl prints a newline)

So long as I is less than N , the equality (unification)


predicate will fail and back-tracking will pursue another
alternative for natural . If I = N succeeds, however,then the
cut will be executed, committing us to the current (final)
choice of I , andsuccessfully terminating the loop.
e)
Individual characters are read and written with get
and put .
f)Input and output can be redirected to different files using
see and tell .
g)

Read & write

h)

get acts as :

get(X) :- repeat, get0(X), X >= 32, !.


i) repeat acts as

repeat.
repeat :- repeat.
5.

DATABASE MANIPULATION
5.1. Prolog programs as data
5.2. Adding to database while pgm running:
a)

?-assert(rainy(chennai))

5.3. Removing
a)

?-retract(rainy(chennai))

b)

?-retractall

for removing all

c)
5.4. FUNCTOR
Individual terms in Prolog can be created, or their contents
extracted, using the built-in predicates functor , arg , and =.. .
The goal functor(T, F, N) succeeds if and only if T is a term
with functor F and arity N :
?- functor(foo(a, b, c), foo, 3).
Yes
?- functor(foo(a, b, c), F, N).
F = foo
N=3

?- functor(T, foo, 3).


T = foo(_10, _37, _24)
5.5. ARGS

The goal arg(N, T, A) succeeds if and only if its first two


arguments ( N and T )are instantiated, N is a natural number,
T is a term, and A is the N th argument of T :
?- arg(3, foo(a, b, c), A).
A=c

5.6. DISADVANTAGES
a)
Parts of Logic not covered (eg: disjunction with more
than one non-negated term.)
b)

Evaluation order

c)

Negation and the Closed World Assumption

You might also like