Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Combinatory logic wikipedia , lookup
Falcon (programming language) wikipedia , lookup
Lambda calculus wikipedia , lookup
Lambda calculus definition wikipedia , lookup
Anonymous function wikipedia , lookup
Closure (computer programming) wikipedia , lookup
Lambda lifting wikipedia , lookup
Common Lisp wikipedia , lookup
LISP Lecture 4 LISP John McCarthy and Marvin Minsky formed MIT’s AI Project in 1958. McCarthy developed LISP in 1958 –1959. Suggested reading: John McCarthy’s home page http://www-formal.stanford.edu/jmc/ Books in UBE library 1. Common LISP by Guy Steele Jr. (254) 2. Common LISP and Artificial Intelligence by Pattrick R. Harrison (144) Functional Programming • Imperative languages are based on Von Newman Architecture. • Functional programming paradigm is based on mathematical functions. • Mathematical function is mapping of members of one set, called the domain set, to another set called the range set. F(x) = 2x + 5 Functional Programming • Evaluation is controlled by recursion and conditional expressions rather than by sequencing and iterative repetition that are common to imperative languages. • Imperative languages refer to values stored in memory locations, so side effects are generated. • In mathematical functions there are no variables in the sense of imperative languages, so there can be no side effect. Functional Programming • Naming a function can be separated from defining a function. Lambda notation is devised to define a nameless function. (((x) x*x*x) (2)) Functional Forms • A high order function, is one that either takes functions as parameters or yields a function as its results, or both. Function composition hfg If f(x) x + 2 g(x) x * 3 Then, h(x) f(g(x)), or h(x) (3 * x) + 2 Functional Forms Construction • Is a functional form that takes a list of functions as parameters and collects the results in a list. Let f(x) x * x g(x) x * 3 h(x) x / 2 then, [f, g, h](4) yields (16, 12, 2) Functional Forms Apply-to-all • Is a functional form that takes a single function as a parameter and applies it to a list of arguments. Let h(x) x * x then, (h, (2, 3, 4)) yields (4, 9, 16) Fundamentals of Functional Programming In imperative programming an expression is evaluated and the result is stored in memory location which is represented as a variable in the program. A purely functional programming language does not use variables and assignment statements. Without variables iterative constructs are not possible. Repetition must be done by recursion. The execution of a function always produces the same result when given the same parameters. This is called referential transparency. Fundamentals of Functional Programming Although functional languages are often implemented with interpreters, they can also be compiled. Functions in imperative languages have restrictions on the types of values that can be returned. In many languages only scalar types are allowed. More importantly, they can not return a function. Imperative languages may have functional side effects. LISP • LISP was the first functional programming language. • With the exception of the first version all LISP dialects include imperative language features such as, imperative style variables, assignment statements, and iteration. Symbolic Expressions, the Syntactic Basis of LISP • The syntactic elements of the LISP programming language are symbolic expressions. • Both programs and data are represented as s-expressions. An sexpression may be either an atom or a list. • Symbolic atoms are composed of letters numbers and certain nonalphanumeric characters (* - + $ % ^ &_ > < ) • A list is a sequence of either atoms or other lists separated by blanks and enclosed in parentheses. Examples • ‘(A B C D) • ‘(A (B C) D (E (F G))) (function_name arg_1 … arg_n) Example (+57) evaluates to 12. Examples • ‘(1 2 3 4) • ‘(likes bill ?X) • (- (+ 3 4) 7) 0 • (=(+ 2 3) 5) t • (list 1 2 3 4) (1 2 3 4) • (nth 0(list a b c d)) a Concepts Behind LISP • From this emerged a universal LISP function that could evaluate any other function in LISP. • The first requirement for the universal LISP function was a notation that allowed functions to be expressed in the same way data was expressed. • Function calls were specified in a prefix list form called Cambridge Polish • In evaluating a function LISP first evaluates its arguments and then applies the function indicated by the first element of the expression to the results of these evaluations. For example in evaluating the expression (+ (* 2 3) (* 3 5)) • LISP first evaluates the arguments (* 2 3) and (* 3 5). These results are then passed to the top level addition which is evaluated, returning 21. Definition S-Expression An s-expression is defined recursively: 1. An atom is an s-expression. 2. If s1, s2,...,sn are s-expressions, then so is the list (s1, s2,...,sn). Evaluating an s-expression • A list is a non-atomic expression. • In evaluating an s-expression: – If the s-expression is a number, return the value of the number. – If the s-expression is an atomic symbol, return the value bound to that symbol; if it is not bound then it is an error. – If the s-expression is a list, evaluate the second through the last arguments and apply the function indicated by the first argument to the result. Control of LISP Evaluation: quote and eval The purpose of the quote is to prevent evaluation of sexpression that should be treated as data rather than an evaluable form. (quote(a b c )) (quote(+1 3)) (list(+1 2) (+ 3 4)) (list ‘(+ 1 2) ‘(+ 3 4)) (>(* 5 6) (+ 4 5)) (‘(a b c )) (‘(+ 1 3)) (3 7) (a b c) (+ 1 3 ) ((+ 1 2) (+ 3 4)) t eval is a complement to quote. (quote(+ 2 3)) (eval(quote(+ 2 3))) (+ 2 3) 5 Programming in LISP: Creating New Functions LISP supports a large number of built in functions – – – – – – Arithmetic functions supporting both integers and real numbers. Program control functions List manipulation and other data structuring functions. Input/Output functions Forms for the control of function evaluation Functions for the control of the environment and operating system. (defun square(x) (* x x)) >(square 5) 25 ; causes 5 to be bound to x (defun <function name> (<formal parameters>) (<function body) ) (defun hypotenuse(x y) (sqrt (+ (square(x)) (square(y)))) Program Control in LISP: Conditionals and Predicates cond takes as arguments a number of condition - action pairs. (cond (<condition1> <action1>) (<condition2> <action2>) ................ (<conditionn> <actionn>) ) (defun absolute-value(x) (cond ((< x 0) (-x)) ((> = x 0) (x)))) (defun absolute-value(x) (cond ((< x 0) (-x)) (t x))) If clause if takes three arguments (defun absolute-value(x) (if (< x 0 ) (-x) x )) Predicates A predicate is a LISP function that returns nil to indicate ‘false’ and anything other than nil to indicate ‘true’. > (= 9 (+ 4 5)) t >(oddp 4) nil Examples to arithmetic predicates are: <, >, =, oddp, evenp, zerop, plusp, minusp. >(member 3 ‘(1 2 3 4 5)) (3 4 5) All Boolean functions are short circuit in Common LISP. They return a value as soon as the result is determined. >(and(t t nil t)) nil >(or( t nil t t)) t Functions, lists, and Symbolic Computing Using nth it is possible to define access functions for the various fields of a data record. Example Suppose a record consists of the fields name, salary, employee number. >(defun name-field(record) (nth 0 record)) >(name-field ‘((Ada Lovelance) 45000.00 38519)) (Ada Lovelance) >(defun first-name(name) (nth 0(name)) >(first-name (name-field ‘((Ada Lovelance) 45000.00 38519))) Ada list is a built in LISP function. >(list 1 2 3 4) (1 2 3 4) >(defun build-record (name salary emp-number) (list name salary emp-number)) >(build-record ‘((Ada Lovelance) 45000.00 38519)) (Ada Lovelance) 45000.00 38519) Using build record and the access functions we may construct functions that return a modified copy of a record . (defun replace-salary-field(record new-salary)) (build-record (name-field record) new-salary (number-field record))) >(replace-salary-field ‘(((Ada Lovelance) 45000.00 38519) ((Ada Lovelance) 50000.00 38519) 50000.00)) Lists as Recursive Structures The basic functions for accessing the components of a list are car and cdr. car (first) - Takes a list as its argument and returns the first element of the list. cdr (rest) - Takes a list as its argument and returns the list with the first argument removed. >(car ’(a b c )) a >(cdr ’(a b c)) (b c) >(car(cdr ’(a b c d))) b A recursive approach to manipulate list structures to perform an operation on each of the elements of a list 1. If the list is empty quit 2. Perform the operation on the first element of the list and recur on the remainder of the list. Common LISP predicates for list processing are member : Determines whether an s-expression is a member of a list. length : Determines the length of a list. Example: Define ‘my-member’ which takes an atom and a list as arguments and returns nil if the atom is not present in the list, otherwise returns the portion of the list containing the atom as the first element. (defun my-member(element list) (cond((null list) nil) ((equal element(car list)) list) (t (my-member element (cdr list)))) >(my-member 4 ‘(1 2 3 4 5 6)) (4 5 6) (defun my-length(list) (cond((null list) 0) (t (+ (my-length (cdr list) 1))))) cons is a basic list constructor (cons ’A ’(L I S)) (A L I S) (cons ’A ’B) (A . B) (cons ’(A) ’(L I S)) ((A) L I S) (cons ’A (cons ’B (cons ’C ‘D) ) ) (A B C . D) (defun filter-negatives (number-list) (cond ((null number-list) nil) ((plusp (car number-list)) (cons (car number-list) (filter-negatives (cdr number-list)))) (t (filter-negatives (cdr number-list))))) >filter-negatives ‘(1 -1 2 3 -4 -5 6) (1 2 3 6) car and cdr tear lists apart and drive the recursion ; cons selectively constructs the result as the recursion unwinds. Recursion is used to scan the list element by element, as the recursion unwinds the cons function reassembles the solution. If cons is called with two lists as arguments it makes the first of these a new first element of the second list, whereas append returns a list whose elements are the elements of the two arguments: >(cons ’(1 2) ‘(4 5 6)) ((1 2) 4 5 6)) >(append ’(1 2) ‘(4 5 6)) (1 2 4 5 6) Lists are powerful representations for tree structures especially for search and parse trees. In addition nested lists provide a way of hierarchically structuring complex data. (1 2 3 4) ((1 2) 3 4) car-cdr recursion adds one more dimension to simple cdr recursion. (defun count-atoms (list) (cond ((null list) 0) ((atom list) 1) (t (+(count-atoms(car list)) (count-atoms(cdr-list)))))) >(count-atoms ‘((1 2 ) 3 (((4 5 (6))))) 6 Functional Programming (set ‘inc 0) (defun f(x) (set ‘inc(+ inc 1)) (+ x inc)) >(f 4) 5 >(f 4) 6 In this example x is a bound variable where inc is a free variable. All the variables that appear as the formal parameter of a function are bound variables, and all the other variables that appear in the body of the function are free variables. When a function is called any bindings that a bound variable may have in the global environment are saved and the variable is rebound to the calling parameter. After the function has completed execution, the original bindings are restored. Thus setting the value of a bound variable inside a function body has no effect on the global bindings of that variable As it is seen from the example free variables in a function definition are the primary source of side effects in functions. (defun fo(x) (setq x (+ x 1)) (x)) The Assignment of Value SETQ : The variable is assigned the value of the form. (SETQ X 23) ;x assigned 23 SET takes only one pair. The first one is a symbol and the second one is a value. Both arguments are evaluated and the value of the second argument is returned. SETF : It is a general form of SETQ. First element is a memory location rather than a variable name. Place can refer to locations other than the value cell of the variable. The Assignment of Value (SETF A 100 B 200 C 300 D 400) (VALUES A B C D) >> 100 200 300 400 (SETF A ‘B) (VALUES A B C D) >> B 200 300 400 (SET A 999) (VALUES A B C D) >> B 999 300 400 ;arguments are evaluated The Assignment of Value setf regards the first argument as naming a memory location. >(setf x ‘(a b c)) (a b c) >x >(setf(cdr x) ‘(2 3)) (a b c) (2 3) >(setf(car x) 1) >x 1 (1 2 3) >x (1 b c) Pattern Matching in Lisp match takes two arguments and returns t if the expressions match. Matching requires that both expressions have the same structure as well as having identical atoms in corresponding positions. >(match ‘(likes bill wine) ‘(likes bill wine)) t >(match ‘(likes bill ?) ‘(likes bill wine)) t >(match ‘(likes bill ?) ‘(likes ? wine)) t High-Order Functions and Procedural Abstraction Functions that take other functions as parameters or return them as results are called higher-order functions and constitute an important tool for procedural abstraction. (defun filter-evens (number-list) (cond (null number-list) nil) ((oddp (car number-list)) (cons (car(number-list) (filter-evens (cdr number-list))) (t (filter-evens (cdr number-list))))) funcall takes as arguments a function and a series of arguments and applies that function to those arguments: >(funcall ‘plus 2 3) 5 (defun filter (list-of-elements test ) (cond(null list-of-elements) nil) ((funcall test(car number-list)) (cons(car(number-list) (filter (cdr list-of-elements) test)) (t (filter (cdr list-of-elements) test))))) The function, filter applies the test to the first element of the list. If the test returns non-nil it conses the element onto the result of filtering the cdr of the list; oterwise it just returns the filtered cdr. >(filter ‘(1 3 -9 5 -2 -7 6) ‘plusp) >(filter ‘(1 a b c 5 7) ‘numberp) (1 3 5 6) (1 5 7) Another important class of higher-order functions consists of mapping functions. >(mapcar ( ‘plus ‘(1 2 3) ‘(2 4 6))) (3 6 9) Functional Arguments and Lambda Expressions Lambda expressions allows the programmer to separate a function definition from the function name. Without lambda expressions the programmer must define every function in the global environment using a defun even though the function may be used only once. >(funcall ‘(lambda( x y) (+ (*x x) y)) ( 2 3)) 7 >(mapcar ‘(lambda(x) (* x x)) ‘(1 2 3 4 5)) (1 2 9 16 25) Data types in Common LISP Built in types are: integers, floating numbers, strings and characters. LISP also includes structured types as arrays, hash tables, sets, and structures . Unlike other strongly typed languages as Pascal, in Lisp it is the data objects that are typed rather than variables. Any LISP symbol may bind to any object; the object itself is typed. Consequently LISP implements run time type checking. A Brief Overview LISP is characterized by the following ideas (McCarthy): 1. Computing with symbolic expressions rather than numbers. 2. Representation of symbolic expressions and other information by list structure in computer memory. 3. Representation of information on paper, from keyboards and in other external media mostly by multi-level lists and sometimes by S-expressions. It has been important that any kind of data can be represented by single general type. 4. A small set of selector and constructor operations expressed as functions, i.e. car, cdr and cons. A Brief Overview (Continued) 5. Composition of functions as a tool for forming more complex functions. 6. The use of conditional expressions for getting branching into function definitions. 7. The recursive use of conditional expressions as a sufficient tool for building computable functions. 8. The use of -expressions for naming functions. 9. The storage of information on the property lists of atoms. A Brief Overview (Continued) 10. The representation of LISP programs as LISP data that can be manipulated by object programs. This has prevented the separation between system programmers and application programmers. Everyone can “improve” his LISP, and many of these improvements have developed into “improvements” to the language. 11. The conditional expression interpretation of Boolean connectives. 12. The LISP function eval that serves both as a formal definition of the language and as an interpreter. 13. Garbage collection as the means of erasure. 14. Minimal requirements for declarations so that LISP statements can be executed in an on-line environment without preliminaries. 15. LISP statements as a command language in an on-line environment. Coding Semantic Networks with Lisp • Suppose that we would like to develop code which will allow us to reason about elecrical connectivity and part/subpart relationships within this diagram. • We will use triples for part_of and connected_to relations and further specify if the relation is transitive and/or commutative. Semantic Networks - Example Semantic Networks - Example (setq known_facts ‘( ( part-of ignition-system ground) (part-of ignition-system battery) (part-of ignition-system ignition-switch) (part-of ignition-system coil) (part-of ignition-system distributor) (part-of battery positive-pin) (part-of battery negative-pin) (part-of coil output-terminal) (part-of coil primary-winding) (part-of coil secondary-winding) (part-of distributor breaker-points) (part-of disributor rotor) (part-of distributor lead) (number-of lead 4) (number-of spark-plug 4) (connected-to ignition-switch positive-pin) (connected-to primary winding ignition-switch) (connected-to negative-pin ground) (connected-to ground breaker-points) (connected-to ground spark-plug) (connected-to primary-winding secondary-winding) (connected-to primary winding output-terminal) (connected-to output-terminal breaker-points) (connected-to secondary-winding rotor) (connected-to rotor lead) (connected-to lead spark-pluug) (transitive connected-to) (transitive part-of) (commutative connected-to) ) ) Semantic Networks - Example What sort of questions would we like to answer using this knowledge base? (connected-to rotor ground) ;; Is the rotor connected to ground? (and (connected-to positive-pin ground) (connected-to negative-pin ground) (or (part-of distributor positive-pin) (part-of distributor negative-pin) ) ) ;; Are both the positive pin and the negative ;; pin connected to ground and is either of them ;; part of the distributor? ) Semantic Networks - Example (find ‘(and (connected-to rotor ground)) ;; Is the rotor connected to ground? ) (find ‘(and ) (connected-to positive-pin ground) (connected-to negative-pin ground) (or (part-of distributor positive-pin) (part-of distributor negative-pin) ) ) ;; Are both the positive pin and the negative ;; pin connected to ground and is either of them ;; part of the distributor? Coding Semantic Networks Initialization function modifies the fact base by adding the inverse of all commutative facts. (defun initialization ( ) (let (commut-facts (matcher ‘(commutative *) known-facts))) (setq known-facts (append known-facts ;;merges known-facts with the inverse list (apply ‘append ;;creates the list of inverse facts for commutative facts (mapcar ‘(lambda (itm) ;;itm comes from commut-facts ;; (‘commutative connected-to’) (commut (matcher (list (cadr itm) ‘* ‘* ) known-facts ) ) ) ;;matcher is called with (‘connected to’ * *) and ;;known-facts commut-facts)))) ) ) Coding Semantic Networks On the top most level is the find function. It checks for a prefixed and or or then mapcar’s eval clause across the relationships. (defun find (p-list ) (cond ((null p-list) t) ((equal (car p-list) ‘and) (and-lst (mapcar ‘eval-clause (cdr p-list) (dupl nil (length (cdr p-list) ) ) ) ) ) ((equal (car p-list ) ‘or) (or-lst (mapcar ‘eval-clause (cdr p-list) (dupl nil (length (cdr p-list) ) ) ) ) ) ((atom (car p-list)) (printc “error: bad list”) nil ) (t (and-lst (mapcar ‘eval-claus p-list (dupl nil (length p-list)))) )) ) Coding Semantic Networks commut function interchanges the attributes within commutative facts (defun commut (lst ) (mapcar ‘(lambda (itm) ;;itm comes from lst (list (car itm) (caddr itm) (cadr itm)) ) lst) ) Coding Semantic Networks The matcher function retrieves all facts that match the given pattern. (defun matcher (pat f-list) (apply ‘append (mapcar ‘(lambda (item) (cond ( (match-fact pat item) (list item) ) ) ) f-list) ) ) The match-fact function compares a single fact with a pattern to see if there is a match. (defun match-fact (pat data) (cond ( (and (null pat) (null data) t) ( (or (null pat) (null data)) nil) ( (or (equal (car pat) ‘* ) (equal (car pat) (car data)) ) (match-fact (cdr pat) (cdr data))) )) ) Coding Semantic Networks Eval-clause function verifies that each pattern has a match in the database of known facts. Because embedded ands and ors can occur, it must check for these embedded clauses and recursively evaluate them. If a pattern is not directly found in the database, the relation is checked if transitive. Should the relation be transitive, the transitive semantics are applied through the call to trans-eval-clause. depth-list keeps track of all visited nodes as the function performs a depth first search of transitive relations. Coding Semantic Networks (defun eval-clause (clause depth-list) (cond ( (equal (car clause) ‘and) (and-lst (mapcar ‘eval-clause (cdr clause) (dupl nil (length (cdr clause))))) ) ( (equal (car clause) ‘or) (or-lst (mapcar ‘eval-clause (cdr clause) (dupl nil (length (cdr clause))))) ) ( (matcher clause known-facts) ) ( (and ( matcher (list ‘transitive (car clause) ) known-facts) (not (member (cadr clause) depth-list) ) (trans-eval-clause clause depth-list) ) ) ( t nil) ) ) Coding Semantic Networks (defun trans-eval-clause (clause depth-list) (let ( (facts (matcher (list (car clause) (cadr clause) ‘*) known-fatcts) ) ) (or-lst (mapcar ‘eval-clause (modify facts (caddr clause) ) (dupl (cons (cadr clause) depth-list) (length facts) ) ) ) ) ) Coding Semantic Networks The modify function is used by transitive relationships to construct a new set of patterns that must be examined. The transitive relation (rel fact-a fact-c) is tried to be proven by first locating all the facts of the form (rel fact-a fact-b). These facts are then rewritten by the modify function into the format (rel fact-b fact-c). lst contains the set of retrieved facts, and itm contains the fact-c (defun modify (lst itm) (mapcar ‘(lambda (lst-itm) (list (car lst-itm) (caddr lst-itm) itm)) lst) ) Coding Semantic Networks The and-lst and or-lst functions take a list of true or false values and apply a logical AND or OR to them. (defun and-lst (lst) (cond ((null lst) t) ((car lst) (and-lst (cdr lst) ) ) ( t nil) ) ) (defun or-lst (lst) (cond ((null lst) t) ((car lst) t) ( t or-lst (cdr lst)) )) ) The final function dupl creates a list containing cnt copies of list. (defun dupl (lst cnt) (cond ( ( zerop cnt) nil) (t (cons lst (dupl lst (1-cnt)))) ) )