Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functional Languages Early in AI research, there was a need for symbolic computing handling symbols instead of numbers or strings recursion Design goals.

Similar presentations


Presentation on theme: "Functional Languages Early in AI research, there was a need for symbolic computing handling symbols instead of numbers or strings recursion Design goals."— Presentation transcript:

1 Functional Languages Early in AI research, there was a need for symbolic computing handling symbols instead of numbers or strings recursion Design goals of functional approach programs would comprise functions and function calls, utilizing recursion as much as possible controlled through loops, rather than a series of imperative statements with local variables Why interpreted? most programmers would build programs in chunks, testing each part out using the interpreter, and then only using the compiler when done Lisp was used extensively for AI research Expert Systems, Natural Language Understanding, Machine Learning, Knowledge Representation, Speech/Vision Understanding, Robotics, Tutorials

2 Lisp The earliest functional language was not Lisp, but Lisp was the successful language to come out of this research Some details on Lisp Lisp began as a purely functional language although it picked up many imperative features (loops, go to statements, local vars, etc) from other languages over time Lisp is interpreted (although compilers later became available) leading to the ability to develop programs in a piecemeal fashion eventually, Lisp compilers for better performance Lisp initially was dynamically scoped but later Lisp was statically scoped Lisp uses only implicit heap dynamic variables

3 Functional Forms A function maps from a domain set to a range set
the range of these two sets is determined by the function A functional form is a higher-order function, that is, a function that applies to functions this can either be a function that accepts a function as a parameter, or a function that returns a function these are important in Lisp as they allow functions to generate new functions (that is, code that can produce code)

4 Mathematical Function (MF)
A mathematical function (MF) is a mapping of members of one set, called the domain set, to another set, called the range set Determine the domain set and the range set of the following MF

5 Mathematical Function (MF)

6 Functional Form Construction Apply to all
a functional form in which the result of one function is applied to a second function (nested functions) example: f(x) = x + 2, g(x) = 3 * x, h(x) = f °g = f(g(x)) = 3*(x+2) Apply to all a functional form in which the function is applied to a list of parameters, returning a list of values example: (using f from above) apply(f(2, 5, 12)) = (4, 10, 14)

7 Fundamental of LISP In a typeless language, we do not declare variables, and variables are merely pointers that can point to any type of data In early Lisp, there were NO local variables, only parameters Data Structures are either atoms and lists atom – a literal value (char, string, number) usually denoted as atom hello 31415 () list – nil or ( x ) where x is an atom, a series of atoms, or a sub list, or any combination of these example of a list (A (B C D) E F) Why lists? It was thought that AI programs would process lists of values. For instance, a natural language understanding system would input a sentence which should be thought of as a list of primitives (words) rather than a string. Lists could also be defined to denote a hierarchical structure (a list could contain sublists), unavailable through arrays or strings. Further, the decision to store both data and code in list form allowed a program to modify code – any list, whether it is data or code can be manipulated.

8 Fundamental of LISP In Lisp, functions are stored in lists and written in prefix notation form of a Lisp function is: (function_name param1 param2 …) examples: (+ 5 7)  returns 12 (equal? a b) returns T (true) if a = b, nil (false) otherwise (/ (+ a b) (- c d)) returns (a + b) / (c – d) (cube x)  returns x3 Functions can also be written as Lambda expressions a Lambda expression is an unnamed function in which the parameters are specified after the function e.g. (lambda (x) (* x x)) (5) 25

9 Representing Lists CAR CDR A B C D E F ( A ( D E F ) B C )
Each list node consists of a data structure (as shown to the right) consisting of two pointers, the CAR points to the item being stored in that node, the CDR points to the next node The terms CAR and CDR are historical, named after registers in an early machine that ran Lisp A B C D E F ( A ( D E F ) B C ) The CDR of a node can equal to nil (equivalent to null or NULL in Java and C) CDRs for C & F are nil The terms CAR and CDR are historical. The earliest computer that would run Lisp used two registers for a list item, the Content Address Register and the Content Decrement Register. The first register would store the atom to be stored in that list node and the second register would store the pointer to the remainder of the list. Notice that the CAR and CDR roughly represent these two items as defined in a C struct: struct node { void *data; struct node *next; }; Notice that the datum is pointed to, rather than the typical approach in C where the datum is physically stored in the struct. I used void for the data type because Lisp is typeless – the atom being pointed to can be any legal type.

10 Lisp and the Eval Function
Lisp’s primary function is EVAL which evaluates a list or atom at run-time functions are special cases of lists: they are lists whose car is a function name and whose cdr is a list of parameters EVAL will evaluate the function name on the parameters that is, (EVAL lis) does (EVAL (car lis) (cdr lis)) this makes Lisp an interpreted language – the eval function is the interpreter original Lisp was supposed to be similar to FORTRAN in its appearance, but this was not practical lists are known as s-expressions (symbolic expressions) and can represent either data or functions

11 Lisp and the Eval Function
Note that evaluating a list which is not a function will return an error for instance if lis1 is (a b c d) then (eval lis1) would attempt to evaluate a on (b c d) but a is an atom, not a function! To define a function, we use the following notation: (function_name (LAMBDA (arg1 … argn) expression)) where function_name is the name of the function to be called by other functions and where expression consists of lists of Lisp function calls

12 Example Math Functions in Lisp
42 returns 42 `42 returns 42 A returns an error but `A returns A (* 3 7) returns 21 ( ) returns 20 (- 5 6) returns -1 ( ) returns 6 (- 24 (* 4 3)) returns 12 (> 5 6) returns nil (false) (= 5 (+ 2 3)) returns t (true) (* (+ 5 4) (- 8 (/ 6 2)) returns 45 (quote a) or `A means to take something literally, do not evaluate it A without the ` would be interpreted as a variable, but if A has not already been assigned a value By “returns”, it means if you type in the item, the interpreter uses it as input and applies the eval function on it, returning the item indicated above. Assume A is a variable that had previously been set to store 5. If you type in A, it returns 5. If you change A to store ’A, then typing in A returns A (not ’A because the quote is only used upon input to avoid the eval function).

13 Variables vs. Symbols and Lists
Variables point to data items which are either symbols (similar in ways to strings) or lists a variable is denoted by its name (e.g., A) An atom or list is denoted using a quote mark as in `A or `(A B C)

14 Variables vs. Symbols and Lists
To create a symbol, use the function QUOTE as in (QUOTE A) which returns ’A or use the shorthand ’A note that ‘ has a different meaning in Lisp to ’ as the ‘ is used in macro definitions, something we will briefly discuss later Notice that `(+ 3 5) does not return 8, it returns the literal list (+ 3 5) because ` says “do not evaluate this” we could evaluate this list by doing (eval `(+ 3 5)) which would return 8 so the ` will allow us to construct a list whether the list stores data or code, and the eval function will allow us to execute a list that is code

15 Why Not Lisp? Lisp was a pioneering programming language in AI and functional programming, but it had many problems The lack of variables led to the programmer having to be tricky in how to use recursion Dynamic scoping was also a problem We concentrate our examination on Lisp by looking at Scheme and later Common Lisp, rather than Lisp itself because it is awkward and difficult

16 Scheme Scheme was one of many versions of Lisp that adds functionality to the language Scheme emerged from MIT in the mid 70’s characterized by a small subset of Lisp features, static scoping and classes Scheme continues to be taught today as an example of a functional language although Scheme itself has not been used much in AI (AI tends to use Common Lisp today if it uses any version of Lisp at all)

17 Some Functions in Scheme
CAR – content of address register (returns first item of a list) CDR – content of decrement register (returns remainder of list) EQ? – equal (for atoms or lists, returns T or nil) MEMBER – membership (is a given item in this list?) ATOM? – is the datum an atom? (T or nil) LIST? – is the datum a list? (T or nil) NULL? – is the datum a nil pointer or something? (T or nil) EVEN?, ODD?, ZERO? – self explanatory (T or nil) =, <>, <, >, <=, >= – self explanatory (T or nil) CONS – a list constructor (we’ll go into more detail later) LIST – an alternative list constructor (returns a list) IF statement: (IF (condition) (then clause) (else clause) ) returns whatever the then clause or else clause returns COND – conditional statement used like a nested if-else structure (we’ll see more examples of this momentarily) Here are some examples. Assume A is 5, B is 6, C is 11, D is ’(A B C) and E is ’(C D) (EVEN? A) returns nil (ODD? C) returns T (EVEN? (+ A C)) returns T (ATOM? B) returns T (LIST? A) returns nil (LIST? D) returns T (MEMBER (CAR E) D) returns T since the (CAR A) is ’C and ’C is in D (EQ? (CDR D) E) returns nil (IF (ODD? B) (+ A B) (- A B)) returns-1 (IF (EQ? (CAR E) (CAR (CDR (CDR D)))) D E) returns the list D, or (A B C)

18 Assignments in Scheme Scheme has 3 different ways of assigning values
set!, define, let (set! a b) is essentially a = b, although in this case, it is a pointer assignment where a points to b if b is a literal, then a points to a memory location storing the value of b, otherwise a points at the same memory location as what b points to (set! a ’(a b c)) creates the list of a, b and c and has the variable a point at the list (set! x (+ 6 (- 8 (* 2 1)))) computes the value (6 + (8 – (2 * 1))) or 12, stores it in memory and has x point at that memory location (set! x `(+ 6 5)) points x at the list (+ 6 5) but not 11 if we do then do (eval x), we get 11

19 Assignments in Scheme (‘Cont)
(define a b) is used to bind the name a to the item b, this can be used to bind a constant to its value, or a function name to its code (we do not use define for variables because the value is not permitted to change once assigned) (let ((a 0) b) –creates local variables for a block enclosed in ( ), in this case, a is assigned by 0, and b has no initial value

20 Conditional Examples Form is
(COND (test1 result1) (test2 result2) …) where tests are conditionals and results are functions The first test to return true executes the associated function if(x = = 0) y = 0; else if(x > 0) y = 1; else y = -1; (cond ((eq? x 0) (set! y 0)) ((> x 0) (set! y 1)) (t (set! y –1))) ((<= hours 40) (* hours wages)) (t (+ (* 40 wages) (* (* (- hours 40) wages) 1.5)))) The first set of code above is equivalent to if(x = = 0) y = 0; else if(x > 0) y = 1; else y = -1; The second set of code is if(hours<=40) return hours * wages; else return (hours – 40 * wages * 1.5; The second cond statement is rewritten as an if statement on the right if(hours<=40) return hours * wages; else return (hours – 40 * wages * 1.5;

21 Conditional Examples The IF statement has two forms
(IF (condition) (function1)) – if the condition returns T, the function returns the value returned by function1 (IF (condition) (function1) (function2)) – if the condition returns T, the function returns the value returned by function1; otherwise it returns the value returned by function2 if(hours<=40) return hours * wages; else return (hours – 40 * wages * 1.5; (if (<= hours 40) (* hours wages) (+ (* 40 wages) (* (* (- hours 40) wages) 1.5)))

22 CONS – list constructor
CONS takes two parameters and returns the list constructed by taking the first parameter, and making it the CAR of a list and attaching to it the second parameter as the CDR Since the CDR must be a list, this only works if the second parameter was already a list Examples: (CONS ’A ’( ) ) returns (A) (CONS ’A ’(B C)) returns (A B C) (CONS ’(A) ’(B)) returns ((A) B) (CONS ’(A B) ’(C D)) returns ((A B) C D) (CONS ’A ’((B C))) returns (A (B C)) CAR CDR What do the following CONS statements return? (CONS ’A ’B)  error since the second item must already be a list (CONS ’ (A) ’(B C))  ((A) B C) - you would normally want to instead do: (CONS ’A ’ (B C))  (A B C) (CONS ’ (A B) ’(C)  ((A B) C) (CONS ’A (CONS ’B nil))  (CONS ’A (B))  (A B) (CONS ’A nil)  (A) (CONS ’A (CONS ’(B) (CONS ’C nil)))  (A (B) C) – can you figure out why? A C D A B

23 Defining Functions in Scheme
Form: (DEFINE (funct_name params) body) (DEFINE (square num) (* num num)) so we can now use square as (square x) which returns x2 (DEFINE (second alist) (car (cdr alist)))  Why??? notice that for the parameter, I used alist, this was merely to avoid confusion since list is defined as a function if we do (second ’(a b c d)), it returns ’b (DEFINE (factorial n) (cond ((eq? n 0) 1) (T (* n (factorial (- n 1)))))) (DEFINE (fib n) (if (> n 2) (+ (fib (- n 1)) (fib (- n 2))) 1)) (DEFINE (foo alist) (cond ((null? alist) 0) (T (+ (foo (cdr alist)) 1)))) CAR CDR If n = 0, return 1, otherwise return n * factorial (n-1) The foo function above computes the length of the list. Each of the functions in the slide have only a single parameter. What about functions with multiple parameters? (DEFINE (MAX a b c) (cond ((and (> a b) (> a c)) a) ((and (> b a) (> b c)) b) (t c))) Here is a recursive function for getting the nth item of a list (assuming the first item is at location 1) (DEFINE (NTH alist n) (if (NULL? alist) nil (if (= n 1) (CAR alist) (NTH (CDR alist (- n 1)))))) This function tests alist to see if it is an empty list and if so, returns nil, otherwise if n is 1, it returns the first item of the list (the CAR) otherwise it recursively calls itself with the rest of the list (CDR) and n – 1. What does this function do?

24 More Scheme Functions (DEFINE (factorial n)
(IF (= n 0) 1 (* n (factorial (- n 1))))) (DEFINE (member atm lis) (COND ((NULL? lis) NIL) ((EQ? atm (CAR lis)) #T) (ELSE (member atm (CDR lis))))) Member will return T if the atm is found in the lis (list) and nil if it is not found (member ’d ’(a b c d e f)) returns T (member ’d ’(a b e f j k)) returns nil Member in Lisp and Common Lisp will return the list starting at atm and going to the end of the list, how can we modify Scheme’s member to do this? (DEFINE (append lis1 lis2) (COND ((NULL? lis1) lis2) (ELSE (CONS (CAR lis1) (append (CDR lis1) lis2))))) If we call (append ’(A B) ’(C D E)) we get back (A B C D E) If we call (append ’((A B) C) ’(D (E F))) we get back ((A B) C D (E F)) Lets work through the member function to see how it works (member ’c ’(a b c d e))  since lis is not nil, and since the CAR lis, a, does not equal c, we do the else clause and call member with atm and the cdr of lis (b c d e). Again, lis is not nil, its car is not equal to c, so we recursively call member with atm and the cdr of lis, this time (c d e). In this call, lis is not nil but c does equal the car of lis, so we return T. (member ’c ’(a b d e)) would continue to recursively call member with the cdr of lis until lis was nil and therefore member returns nil.

25 More Examples A function that uses local variables to compute quadratic roots (DEFINE (quadratic_roots a b c) (LET ((root_part_over_2a (/ (SQRT (- (* b b) (*4 a c))) (* 2 a))) (minus_b_over_2a (/ (- 0 b) (* 2 a)))) (DISPLAY (+ minus_b_over_2a root_part_over_2a)) (NEWLINE) (DISPLAY (- minus_b_over_2a root_part_over_2a)))) Two ways to add a list of numbers: (DEFINE (adder lis) (COND ((NULL? lis) 0) (ELSE (+ (CAR lis) (adder (CDR lis)))))) (DEFINE (create-adder lis) (COND ((NULL? Lis) 0) (ELSE (EVAL (CONS ’+ lis))))) What does this second one do? Example of an apply-to-all function (DEFINE (mapcar fun lis) (COND ((NULL? Lis) ( )) (ELSE (CONS (fun (CAR lis)) (mapcar fun (CDR lis)))))) (mapcar (LAMBDA (X) (* x (+ x 1))) ’( )) returns ( )

26 Common Lisp First developed in 1984
Incorporates features of many earlier Lisps including Scheme Around 1988, CL was combined with CLOS (the Common Lisp Object System) to be a hybrid OO+functional language (in the same way that C++ is a combination of C and Smalltalk) Common Lisp is similar to C++ in size and complexity Common Lisp uses static scoping as its default but allows for dynamic scoping

27 Common Lisp Common Lisp includes
a full range of built-in data types including arrays, records, complex #’s, strings, classes powerful I/O operations including streams and formatted I/O imperative features including a wide variety of control structures exception handling (several different forms)

28 Some Common Lisp Functions
PROG a local block where global variables are unaffected by any statements within the block progn is the same except that the block automatically returns the value of the last function executed in the local block New control statements DOTIMES – counter-controlled loop DOLIST – iterator loop, executes loop body once for each list item DO – general purpose loop, can be counter-controlled or logical, much like C’s for-loop

29 Some Common Lisp Functions
Setf for assignment variables declared in let statements initialized to NIL until assigned a value DEFUN – defining functions form: (DEFUN functionname (params) body) body is any single or group of statements, use (let ( ) body) to have local variables and (progn body) for a block (for instance as the if or else clause of an if-else statement) GO – a goto statement (we will see this next) Variations of CAR and CDR: CADR, CDDR, CAAR, CDAR, etc are all available Notice that defun is a bit different from Scheme’s DEFINE. Here, only the params are placed in ( ), not the name of the function.

30 Common Lisp Functions Two member functions Iterative version:
(DEFUN imember (atm lst) (PROG ( ) loop_1 (COND ((NULL lst) (return nil)) ((EQUAL atm (CAR lst)) (RETURN T))) (SETQ lst (CDR lst)) (GO loop_1))) Recursive version: (DEFUN rmember (atm lst) (COND ((NULL lst) NIL) ((EQUAL atm (CAR lst)) T) (T (rmember atm (CDR lst))))) Two length functions Iterative version: (DEFUN ilength (lst) (PROG (sum) (SETQ sum 0) again (COND ((NULL lst) (RETURN sum))) (SETQ sum (+ sum 1)) (SETQ lst (CDR lst)) (GO again))) Recursive version: (DEFUN rlength (lst) (COND ((NULL lst) 0) (T (+ 1 (rlength (CDR lst)))))) The iterative versions of the functions above are merely to illustrate the use of the GO statement. I doubt anyone would actually write code like that. The recursive functions are easy enough to write and understand.

31 More Recursive Demonstrations
The main idea behind Lisp was to use recursion and no local variables while both iteration and local variables (through the let function are available, we are generally discouraged from using either as seen in these examples (defun remove-first (a lis) (cond ((null lis) '( )) ((equal (car lis) a) (cdr lis)) (t (cons (car lis) (remove-first a (cdr lis)))))) (defun member-at-all (a lis) (cond ((null lis) nil) ((listp (car lis)) (or (member-at-all a (car lis)) (member-at-all a (cdr lis)))) ((equal (car lis) a) t) (t (member-at-all a (cdr lis))))) Remove the first instance of the item a from the list lis (defun all-the-same (lis) (cond ((null lis) t) ((or (atom lis) (= (length lis) 1)) t) ((equal (car lis) (cadr lis)) (all-the-same (cdr lis))) (t nil))) The member function looks for a in lis, but what if a is burried inside of further lists? member-at-all sees if a is a member at any level of lis and returns t or nil Determine if the items in lis are all the same, such as ’(a a a) versus ’(a b a)

32 Conclusion Functional languages vs. imperative languages:
variables/memory usage less visible making programming easier, under some circumstances simpler syntactic structures to deal with (everything is a list) concurrency easier to design and implement interpreted nature makes large systems easier to build exploits recursion as much as possible

33 Conclusion Uses of functional languages: mostly used in AI research
Natural Language Understanding (easy parsing partially due to recursive nature) Expert Systems (easy rule format) Knowledge Representation (symbolic capabilities) Machine Learning (dynamic storage) used to teach functional programming used to implement EMACS, MACSYMA and some operating systems


Download ppt "Functional Languages Early in AI research, there was a need for symbolic computing handling symbols instead of numbers or strings recursion Design goals."

Similar presentations


Ads by Google