159'331 Programming Languages - PowerPoint PPT Presentation

1 / 42
About This Presentation
Title:

159'331 Programming Languages

Description:

... bound and so the system can look up the children of X and their ... The reverse reasoning applies if we have the query ? ... We number the nodes (lakes) ... – PowerPoint PPT presentation

Number of Views:17
Avg rating:3.0/5.0
Slides: 43
Provided by: KenHa98
Category:

less

Transcript and Presenter's Notes

Title: 159'331 Programming Languages


1
159.331 Programming Languages Algorithms
  • Lecture 23 - Logic Programming Languages - Part
    2
  • Relations and Data Structures

2
Relations
  • Although the use of logical variables may look
    similar to that in imperative or functional
    programming - there is a very important
    difference
  • In matching a goal with the head of a rule the
    system will make any necessary bindings
  • For example, to answer the query
    coauthor(ullman,aho) the variables X and Y in the
    head of the clause
  • coauthor(X,Y) ? author(X,Book), author(Y,Book).
  • Were bound to the values ullman and aho
  • This is similar to call-by-value parameter passing

3
  • The binding can work the other way around and
    pass a value from the head of the goal to a
    variable in the query. For example
  • ?- author(X, database_book).
  • Asks if an X exists that is an author of the
    database book. The system will match against
    its facts and should find that
    author(ullman,database_book)
  • To make this fact and the query clause equal, the
    system will bind the variable X in the goal to
    the value ullman
  • This is roughly like call-by-result parameter
    passing
  • Logic variables can be used both as input and as
    output arguments, without having to specify in
    advance

4
  • Some Prolog programs can in fact run backwards
    and forwards with equal ease
  • Unlike in Ada for example, where the programmer
    has to specify in the procedure header how each
    parameter is used
  • In essence the Horn clause for author does not
    define a procedure or a function but a relation
  • A procedure maps input arguments onto output
    arguments - for example compute the author of
    B
  • A Horn clause specifies a relation that holds
    between different arguments - for example X is
    an author of B
  • This relation concept differentiates logic
    programming

5
Data Structures
  • Logic languages also support data structures so
    that we can have arguments that are not just
    variables or constants
  • Structures and Lists are the two most important -
    although in prolog a list is implemented as a
    special case of structure.
  • A structure - also known as a compound term
    consists of a functor and zero or more
    components
  • person( john, 35, mary)
  • Has the functor person and three components
    (name, age and spouse in this example)

6
A Structure Example
  • Suppose we have the rule
  • international_access-code( 44, X ) ? in_UK(X).
  • And the query
  • ?- international_access-code( Code, london ).
  • The predicate international_access_code has a
    single argument which is a list
  • The system will bind X to london and Code to 44
    and will try to prove in_UK(london)
  • Information is hence passed both ways through a
    single structured argument (a list in this case)

7
Lists
  • The list is the structure most often
    encountered in logic languages
  • For example 1, 4, 9, 16, 25
  • Much of the power of logic language s comes
    from the ability to make the matching rules work
    for data structures
  • Lists in Prolog, like in Lisp, are treated as
    head and tail - denoted Head Tail in
    Prolog
  • So 1,4,9,16,25 is equivalent to 1
    4,9,16,25

8
  • Our list notation can also be used for splitting
    a list (as we used in Miranda Haskell)
  • If a list Head Tail is matched against
    another list, the variable Head is
    (automatically) bound to the first element of the
    list and Tail is bound to the rest of the list.
  • We can use this to write a member relation
  • member( X, X Tail ).
  • member( X, Y Tail ) ? member( X, Tail ).
  • The declarative meaning is that X is a member if
    it is the first element or if it is a member of
    the tail of a list (recursive)

9
  • A query such as
  • ?- member( 4, 1,2,3,4,5,6 ).
  • Results in four recursive invocations of member
    before it succeeds.
  • Appending to a list is also useful
  • append( , L, L ).
  • append( X L1, L2, X R ) ? append( L1,
    L2, R ).
  • First clause is the escape hatch for the
    recursion - it says that appending an empty
    list onto any list is the same list
  • The second says that the concatenation of XL1
    and L2 yields XR if the concatenation of L1
    and L2 yields R

10
  • Working through ?- append( 1,2, 3,4, Result
    ).
  • First clause fails (obviously as 1,2 is not
    an empty list
  • Second clause will match to
  • append( X L1, L2, XR )
  • Binding X to 1 L1 to2 L2 to 3,4
    and Result to 1R
  • Next recursion append( 2, 3,4, R ) is
    done, binding X? to 2 L1? to L2? to
    3,4 and R to 2 R?
  • And next recursion append ( , 3,4, R? )
  • (note we have used prime ? to denote variables
    during the recursion)
  • Recursion stops as it matches the escape-hatch
    clause

11
  • So we end up with
  • R? L 3,4
  • And
  • R 2 R? 2,3,4
  • And
  • Result 1 R 1,2,3,4
  • So the final result of the query is the list
    1,2,3,4
  • Which is the concatenation we wanted.
  • Hence the power of the declarative relations!

12
Controlling the Search Order
  • Although completeness of search will always find
    a solution if one exists, the resulting
    systematic search can be prohibitively expensive.
  • In many cases parts of the search space can and
    must be pruned
  • A clever search order may find a solution much
    quicker than a random search order
  • Prolog provides a simple mechanism for
    controlling the order, ensuring
  • Alternatives for given clause are always tried
    one at a time, in textual order, and
  • Within the body of a clause, the sub-goals are
    tried one at a time, from left to right.

13
  • So programmers can order the alternatives and
    subgoals to reduce total search time.
  • Prologs search order results in a depth-first
    traversal of the AND/OR tree.
  • However, strict depth-first will not always
    guarantee to find a solution even if one exists!
  • a(1) ? a(1).
  • a(2).
  • Will loop forever on the initial goal ?-x(N).
  • Will try first clause infinitely often, never
    reaching the second. So Prolog does not have the
    completeness of search property.

14
The Cut Operator
  • Prolog also has the cut operator mechanism to
    tell the system not to backtrack in certain
    cases.
  • Consider
  • G0 ? G1, G2, G3, !, G4, G5.
  • The cut operator ! appears between 3rd and 4th
    subgoals in the body.
  • Prolog will try all subgoals initially ignoring
    the cut operator. If however goals to the right
    of the ! fail and cause backtracking, the
    system will not backtrack across the !
  • If G5 fails, system will try an alternative
    for G4, but if G4 fails it will not try another
    G3, hence giving up on G0

15
  • The notion is that success of G1, G2 and G3 are
    sufficient for G0 to succeed. So G4 and G5
    should now also succeed. If they do not it is an
    indication that something is wrong and that other
    solutions to G1, G2 and G3 will not help and
    neither will it help to try other solutions to
    G0.
  • It is up to the programmer to specify this based
    on extra knowledge of the application problem.
  • The programmer might know, for instance, that
    only one of several alternatives for a certain
    goal (such as G3) can possibly succeed.

16
  • So if a successful alternative for this sub-goal
    is found, the program can essentially commit
    itself to this choice.
  • A common example is mutually exclusive cases
    such as
  • fee(Age, Fee)? Age lt 18, !, childrens_fee(Fee).
  • fee(Age,Fee) ? Age gt 18, Age lt 65, !,
    adults_fee(Fee).
  • fee(Age,Fee) ?Age gt 65, seniors_fee(Fee).
  • The first argument fully determines the
    alternative, so there is no need for
    backtracking. Use with care - not only gives up
    completeness of search but can also destroy the
    declarative meaning of programs

17
  • Can still be hard to obtain efficient programs
  • If optimal search order depends on dynamic
    conditions, such as values of arguments, this
    cannot be expressed within Prologs static
    mechanisms. For example
  • grandfather(X,Y) ? father(X,Z), father(Z,Y).
  • saying X is grandfather of Y
  • If first argument is bound as in the query
  • ?-grandfather( richard, S ).
  • It is most efficient to solve the leftmost father
    goal first. X is bound and so the system can
    look up the children of X and their children
  • If we do the left-most first, nothing is bound so
    have to examine all fathers - this process is
    potentially very slow if our knowledge database
    is large.

18
  • The reverse reasoning applies if we have the
    query ?-grandfather(G,johnny).
  • Now it is more efficient to start from the
    right-most subgoal first - since Y is bound.
  • Unfortunately in Prolog the search order is
    fixed statically, so it is difficult to write an
    optimal grandfather relation.
  • More fundamentally, formulating a problem
    specification using horn clauses is often not
    enough to obtain an efficient program.
  • For example sorting

19
(No Transcript)
20
  • suppose we write
  • sort( List, SortedList) ?
  • permutation( List, SortedList),
    ordered(SortedList)
  • Which says that SortedList is the result of
    sorting List if SortedList is a permutation of
    List and the elements of SortedList are ordered.
  • (Suppose we have successfully written clauses
    for permutation and ordered )
  • This is correct and would sort the list, but
    as the number of permutations grows very fast
    with size of the list, it would be extremely slow
  • We cannot fix it by changing the textual order of
    the clauses or adding some cut operators - we
    really need a way to tell the system how to
    generate permutations more efficiently (other
    than at random)

21
  • A sorting program written in an imperative
    language does not generate random permutations
  • It typically reorders the list in a way that get
    closer and closer to a final ordered solution
  • More efficient solutions mimic traditional
    sorting solutions such as quicksort.
  • The moral of this story is that sometimes
    declarative solutions are too naïve to be
    efficient. Sometimes the programmer does know
    better than the system!

22
Example Programs
  • Logic programming has been used successfully for
    a variety of applications - particularly
    non-numerical ones.
  • Summing, sorting and searching examples will
    hopefully give us some insights into how to
    use a logic programming system

23
Summing
  • Suppose we want to sum all integers from 1 to N
  • Prolog has the infix is operator as in X is 3
    4.
  • It forces evaluation of the expression on the
    right and matches the result with its left
    operand - which is usually an unbound variable,
    so will be bound to the result.
  • The left can also be a value in which case the
    operator tests whether the expression on its
    right (when evaluated) equals the left operand.

24
  • We use the relation sum(N,S) to mean that the
    sum of the integers 1 to N equals S - we can
    define it in two clauses
  • sum(1, 1).
  • sum(N, S) ? N2 is N-1, sum(N2, S0), S is S0 N.
  • The first specifies that the sum of 1 to 1 is 1
  • Second specifies that sum of 1 to N is the sum
    of 1 to N-1 plus N
  • Clause uses predicate sum recursively and binds
    the result to S0
  • It uses the is operator for computing N-1 as
    well as S0 N

25
  • If we use sum in the query ?-sum(2,S).
  • The system tries to match sum(1,1) with sum(2,S)
    which fails
  • Next it tries second clause causing N to be bound
    to 2 and N2 to 1 resulting in recursive call
    sum(1,S0) which matches the first clause and
    binds S0 to 1, and final result of the initial
    goal will be S a 2 3
  • This actually depends upon Prologs search order
    - if we reverse the order of the two clauses it
    will get into an infinite loop

26
  • The is operator is only one way - our predicate
    sum does not work in the opposite direction
  • We might expect
  • ?-sum(N,6).
  • to succeed and bind N to 3 since 123 6
  • However the subgoal N2 is N-1 will produce an
    error message, because N is not bound. So as we
    have implemented it, sum is not a true relation.

27
Sorting
  • We saw earlier how our naïve declaration of the
    sort problem would be very slow
  • So how would we implement something faster such
    as quicksort?
  • Define two clauses qsort and split
  • qsort predicate uses the first element of the
    list to be sorted as a pivot
  • First it splits the list without the pivot into
    two sub-lists
  • The split predicate takes the pivot and a list
    as input and splits the list into two parts

28
(No Transcript)
29
Searching in a Graph
  • Suppose we want to find if there exists a path
    between two given nodes in a directed acyclic
    graph (eg group of lakes connected by rivers)
  • We might represent the graph by a list of its
    arcs
  • We number the nodes (lakes) 1,2,3,4,5,6
  • And give the facts that there is an arc (river)
    from 1 to 2 etc

30
(No Transcript)
31
  • Can now easily test whether a path exists between
    a source and a destination node using the
    following relation
  • path(S,D) ? arc(S,D).
  • path(S,D) ? arc(S, X), path(X, D).
  • First clause is simple case if there is a direct
    arc connecting the two, second clause checks to
    see if there is a direct connection to any other
    intermediate node X
  • The code is short because the system does the
    searching automatically - in an imperative
    language it would have to be programmed
    automatically.

32
  • If we ask ?- path(1,6).
  • System begins with first clause arc(1,6) which
    immediately fails
  • Then it tries arc(1,X) which matches arc(1,2)
    and arc(1,3)
  • Prologs search ordering tries the first one
    first binding X to 2 and leading to the subgoal
  • ?- path(2,6).
  • This fails and the system has to backtrack - it
    undoes its most recent decision and the
    corresponding bindings
  • So X is unbound, then we try arc(1,3) binding X
    to 3 and the subgoal ?-path(3,6) is executed
  • Eventually get a solution since there is a path
    from 3 to 6

33
  • During the search process X takes different value
    s as it is first bound and then unbound by
    backtracking
  • This form of once-off (until backtracking)
    assignment is different from the destructive
    assignment in imperative programming
  • Incidentally, note that our Prolog program will
    get stuck if we have a graph containing cycles -
    it has no means of recording that it has already
    visited a particular (failed) path
  • (Prologs lack-of-completeness-of-search property)

34
Example Language - Prolog
  • Developed by Colmerauer et al, Marseille mid
    1970s
  • Become widely used after Warren (Edinburgh)
    abstract machine shown to provide an efficient
    implementations
  • Prolog based on Horn logic and supports
    structures as its main data apparatus and lists
    as a special case.
  • Typically comes with many built-in predicates -
    some are Meta-Logical and Extra-Logical

35
  • Meta-Logical predicates test the state of
    variables.
  • nonvar checks if a given variable is bound
  • (can use it to write an efficient grandfather
    relation)
  • Extra-logical predicates do not fit into the
    logical programming framework - used for I/O
  • (output predicates cannot be backtracked over
    for instance)
  • Prolog has some useful database operations
    implemented as extra-logical predicates
  • Assert and retract allow you to (dynamically)
    add new facts and rules to the knowledge base
    Prolog is working against

36
  • assert( happy(george) ).
  • assert( ( happy(X) ? married(X) ) ).
  • This is powerful but makes it more difficult to
    analyse Prolog programs statically (eg to
    compile them into machine code)
  • Adding and deleting rules dynamically makes it
    possible to change the program at run time
  • Modern Prolog systems will have special
    declarations for relations that are changed
    dynamically

37
  • Prolog uses depth-first search - if a solution is
    found, the user can force it to backtrack by
    typing a semicolon
  • ?-author(X,awk_book).
  • Xaho
  • Xkernighan
  • no
  • Our typing is an indication we want another
    solution.

38
Other Logic languages
  • Many other Prolog-like systems
  • Alf, CORAL, Lolli, Mercury,ECLiPSe, eLP, GOEDEL
  • See Web search
  • Generally based around Prolog ideas, with
    possible embeddings or interface to other
    languages such C and various pure/impure
    features
  • Usually based around the WAM or an extension.

39
Logic Programming - Summary
  • Logic programming is based on Horn Logic. A Horn
    clause is an if-then rule with one conclusion in
    the then part (head) and zero or more goals in
    the if part (body)
  • Programmer specifies a problem by giving a set of
    Horn clauses describing facts and properties
    about the problem.
  • The user can ask questions to the system by
    giving it goals to prove. The system
    automatically tries to prove the goals using the
    Horn clauses. If the system is unable to prove
    the goal from the Horn clauses it has available,
    it assumes the goal is not true.
  • A logic programming system that has the
    completeness-of-search property will always find
    a proof if one exists. Such systems typically
    use a search strategy based on back-tracking.

40
  • Horn clauses may use logical variables, denoting
    unspecified objects. A logical variable is
    initially unbound. It can be bound only once,
    unless its value is unbound again during
    back-tracking. Binding occurs as a side effect
    of matching a goal with the head of a clause.
  • Horn clauses express relations rather than
    functions. The arguments of a clause are not
    marked in advance as being input or output, but
    can often be used in both ways.
  • Structures and lists are the most important data
    groupings in logic languages.

41
  • For efficiency, the programmer may control the
    order in which alternative clauses for a goal are
    tried as well as the order in which different
    sub-goals in one clause are tried.
  • Prolog is by far the most popular logic language.

42
Logic Programming
  • See Bal Grune Chapter 5
  • Sebesta Chapter 16
  • See the GNU prolog Web Link
  • Next Parallel Programming Paradigm
Write a Comment
User Comments (0)
About PowerShow.com