07.363 Logic Programming: Lecture 8

Pragmatics

  Arithmetic
  Type tests
  Comparisons
  Input/output
  Term manipulation
  


Arithmetic

  Why can't Prolog add?

     ?- 2 = 1 + 1.
    no
  
  To Prolog, 1+1 is a term with functor + and two
  arguments (both 1).  A term with two arguments cannot unify with a
  simple integer.

  How do you do arithmetic then?

  Two ways: peano numbers, and is/2.


Peano numbers

  Use Prolog terms to represent unary numbers:
  
    0, s(0), s(s(0)), s(s(s(0))), etc.
  

  Can compare numbers for equality, inequality, etc. using only
  unification
  
    peano_add( 0,    N, N ).
    peano_add( s(N), M, s(Sum) ) :-
        peano_add( N, M, Sum ).

    | ?- peano_add(s(0), s(s(0)), X ).
    X = s(s(s(0)))

    
    | ?- peano_add(s(0), X, s(s(s(0)))).
    X = s(s(0))
  
  

Real, efficient numbers

  Prolog can evaluate a term consisting of integers, reals and terms of
  built from (+)/2, (-)/2, (*)/2, (/)/2,
  etc.

  Non-logical operation!  Don't expect reversability!
  
    | ?- X is 1 + 1.
    X = 2

    | ?- 2 is X + 1.
    ! Instantiation error in argument 2 of is/2
    ! goal:  2 is _8997+1
  


Type tests

  Prolog is an untyped language.  Runtime type tests are sometimes
  needed.

  integer/1
  float/1
  var/1
  nonvar/1
  atom/1
  atomic/1
  
  
  The tests are non-logical, since they depend on the current state of
  variables.  E.g.

 
    | ?- var(X), X = 1.
    X = 1.

    | ?- X = 1, var(X).
    no
  


Example: symbolic differentiation

    deriv( N, _X, 0 ) :- number(C).
    deriv( X, X,  1 ).
    deriv( U^C, X, C*U^L*DU ) :-
        number(C),
        L is C - 1,
        deriv( U, X, DU ).
    deriv( -U, X, -DU ) :-
        deriv( U, X, DU ).
    deriv( U+V, X, DU+DV ) :-
        deriv( U, X, DU ),
        deriv( V, X, DV ).
    deriv( U*V, X, U*DV+V*DU ) :-
        deriv( U, X, DU ),
        deriv( V, X, DV ).
  



Comparisons

  Compare integers with (>)/2, (<)/2, (>=)/2 and
  (=<)/2. 

  Can also compare terms with (==)/2, (@>)/2, etc.  Useful
  for generic sorting, binary search, etc.

  
    | ?- freda @> fred.
    yes

     ?- foo(bar) @< bar(foo).
    no
  

  Also, compare/3 returns result of comparison (useful for taking
  3-way branch)
  
    | ?- compare(Cmp, foo(bar), bar(foo)).
    Cmp = >
  


Input/output

  All side-effected, non-logical operations (do you really expect
  to backtrack over reading user input???)

  Basic i/o operations include
  
  read/1   Read a term from standard input
  write/1  Write a term to standard output
  get0/1   Read a single character
  put/1    Write a single character
  format/2 Write formatted output (like printf() in C)
  

  Quintus provides a rich set of i/o operations.




Constructing/destructing terms

  How can you write a predicate to substitute all occurences of one term
  with another?

  E.g.
  
    | ?- subst( x+y*(sqr(x)), x, z, Term ).
    Term = z+y*(sqr(z))
  

    subst( X, X, Y, New ) :- !, Y = New.
    subst( Const, _, _, New ) :-
        atomic(Const),
        !,
        Const = New.
    subst( Term, X, Y, NewTerm ) :-
        ???
  

  How to look inside a term when you don't know its name or number of
  arguments?



Functor/3

  functor(Term,Name,Arity) succeeds if Term has principle
  functor Name and Arity arguments.  Can be used with
  Term known to return Name and Arity, or with
  Name and Arity known to construct an uninstantiated
  term.

  E.g.
  
    | ?- functor(foo(a,b), N, A ).
    N = foo
    A = 2

    | ?- functor( Term, foo, 2 ).
    Term = foo(_,_)
  


Arg/3

  arg(ArgNum, Term, Arg) unifies Arg with the
  ArgNumth argument of Term.

  E.g.
  
     ?- arg(2, foo(a,b), X).
    X = b
  



Completing subst/4
 
    subst( Term, X, Y, NewTerm ) :-
        functor(Term, N, A),
        functor(NewTerm, N, A),
        subst(N, Term, X, Y, NewTerm ).

    subst( N, Term, X, Y, NewTerm ) :-
        ( N =:= 0 -> true
        ; arg(N, Term, Arg),
          arg(N, NewTerm, NewArg),
          subst(Arg, X, Y, NewArg),
          N1 is N - 1,
          subst( N1, Term, X, Y, NewTerm )
        ).