Accumulating results Contents Three ways of computing results - - PDF document

accumulating results contents
SMART_READER_LITE
LIVE PREVIEW

Accumulating results Contents Three ways of computing results - - PDF document

Lecture 5 Accumulating results Contents Three ways of computing results during re- cursion Collecting results during recursion Compute lower result, then use it at this level Pass down accumulating value, finalise at base Recurse


slide-1
SLIDE 1

Lecture 5

Accumulating results Contents

  • Three ways of computing results during re-

cursion

slide-2
SLIDE 2

Collecting results during recursion

  • Compute lower result, then use it at this level
  • Pass down accumulating value, finalise at base
  • Recurse on uninstantiated nested value

“Introduction to Artificial Intelligence Programming”, School of Informatics

2

slide-3
SLIDE 3

Get lower result and use it (1)

  • urlength([ ], 0).
  • urlength([_|Rest], Size) :-
  • urlength(Rest, RestSize),

% result from below Size is RestSize + 1. % and use it

“Introduction to Artificial Intelligence Programming”, School of Informatics

3

slide-4
SLIDE 4

Get lower result and use it (2)

factorial(0, 1). factorial(Number, Result) :- NewNumber is Number - 1, factorial(NewNumber, NewResult), % result from below Result is Number * NewResult. % and use it

“Introduction to Artificial Intelligence Programming”, School of Informatics

4

slide-5
SLIDE 5

Get lower result and use it (3)

reverse( [ ], [ ] ). reverse( [Head|Tail], Answer ) :- reverse( Tail, RevTail ), % result from below append( RevTail, [Head], Answer ). % and use it (Not ideally efficient – processing time is proportional to square of length of original list.)

“Introduction to Artificial Intelligence Programming”, School of Informatics

5

slide-6
SLIDE 6

Accumulators

  • Define an auxiliary predicate with an extra argument.
  • The extra argument accumulates the result during the

computation.

  • The base case ensures that the accumulated value is put in

the correct place.

  • The main predicate (with original number of arguments)

invokes the auxiliary predicate.

  • The initial invocation of the auxiliary predicate must

ensure that the initial value of the accumulator argument is appropriate.

“Introduction to Artificial Intelligence Programming”, School of Informatics

6

slide-7
SLIDE 7

Using a numeric accumulator (1)

% From C & M - computing length of list: listlen(List, N):- lenacc(List, 0, N). % Use auxiliary procedure, extra argument: lenacc([ ], Acc, Acc). % make final value the result lenacc([_Head|Tail], Acc, N):- Acc1 is Acc +1, % increase accumulator lenacc(Tail, Acc1, N). % count rest

“Introduction to Artificial Intelligence Programming”, School of Informatics

7

slide-8
SLIDE 8

Using a numeric accumulator (2)

% Counting how many ‘atoms’ in a list, % including inside any nested lists. count(L, R):- countacc(L, 0, R). % initially counter is 0 countacc([ ], Acc, Acc). % make final value the result countacc(X, Acc, W):- % if item is atom, count it atomic(X), W is Acc+1. countacc([Head|Tail], Acc, Res):- % recursively count head and tail, % passing across running total countacc(Head, Acc, Newacc), countacc(Tail, Newacc, Res).

“Introduction to Artificial Intelligence Programming”, School of Informatics

8

slide-9
SLIDE 9

Numeric accumulator, delayed

% Computing length of list: leng(List, Size):- lengaux(List, 0, Size). lengaux([ ], Acc, Res):- % evaluate built-up expression Res is Acc. lengaux([_|L], Acc, Res):- % recurse with bigger expression % (no evaluation yet) lengaux(L, Acc +1, Res).

“Introduction to Artificial Intelligence Programming”, School of Informatics

9

slide-10
SLIDE 10

Trace of delayed evaluation

| ?- leng([a,b,c],P). + 1 1 Call: leng([a,b,c],_205) ? + 2 2 Call: lengaux([a,b,c],0,_205) ? + 3 3 Call: lengaux([b,c],0+1,_205) ? + 4 4 Call: lengaux([c],0+1+1,_205) ? + 5 5 Call: lengaux([ ],0+1+1+1,_205) ? 6 6 Call: _205 is 0+1+1+1 ? 6 6 Exit: 3 is 0+1+1+1 ? + 5 5 Exit: lengaux([ ],0+1+1+1,3) ? + 4 4 Exit: lengaux([c],0+1+1,3) ? + 3 3 Exit: lengaux([b,c],0+1,3) ? + 2 2 Exit: lengaux([a,b,c],0,3) ? + 1 1 Exit: leng([a,b,c],3) ? P = 3 ? yes

“Introduction to Artificial Intelligence Programming”, School of Informatics

10

slide-11
SLIDE 11

Using a list accumulator (1)

A more efficient list-reversal – this stacks elements on to the accumulator. reverse( List, ReversedList ) :- reverse( List, [], ReversedList ). reverse([], List, List). reverse([H|T], SoFar, Reversed) :- reverse(T, [H|SoFar], Reversed). (Processing time is proportional to length of original list.)

“Introduction to Artificial Intelligence Programming”, School of Informatics

11

slide-12
SLIDE 12

Using a list accumulator (2)

Finding all items which appear in both of two lists. intersect(Set1, Set2, Result):- % Start with empty accumulator intersect(Set1, Set2, [ ], Result). intersect( [ ], _ , V, V). % base case 1 % Make accumulator the result intersect( _ , [ ], V, V). % base case 2 % Make accumulator the result intersect([A|L1], L2, Acc, Res):- % If A in L2, remove, leaving RestL2 takefrom(A, L2, RestL2), % Add A to accumulator, work on RestL2 intersect(L1, RestL2, [A|Acc], Res). intersect([_A|L1], L2, Acc, Res):- % If A not in L2, use same accumulator intersect(L1, L2, Acc, Res).

“Introduction to Artificial Intelligence Programming”, School of Informatics

12

slide-13
SLIDE 13

Building on to uninstantiated variable (1)

If item X is in the list List, return a list of the other items;

  • therwise fail. (Assumes X is present at most once).

takefrom(X, [X|List], List). takefrom(X, [Y|List], [Y|Newlist]):- % to build up the result, put Y on to % front of yet-to-be-built list takefrom(X, List, Newlist).

“Introduction to Artificial Intelligence Programming”, School of Informatics

13

slide-14
SLIDE 14

Building on to uninstantiated variable (2)

Finding all items which appear in both of two lists. inboth([ ], _ , [ ]). inboth( _ , [ ], [ ]). inboth([A|L1], L2, [A|Res]):- takefrom(A, L2, RestL2), inboth(L1, RestL2, Res). inboth([ _ |L], L2, Res):- inboth(L, L2, Res).

“Introduction to Artificial Intelligence Programming”, School of Informatics

14

slide-15
SLIDE 15

Summary

  • During recursion, a result value often has to be computed.
  • This can be done by a simple recursive call followed by

some further computation.

  • Alternatively, an auxiliary predicate with an accumulator

argument can be used.

  • A very common form is to recurse on an uninstantiated

structure.

“Introduction to Artificial Intelligence Programming”, School of Informatics

15