1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Lý Thuyết Và Bài Tập Thực Hành Golden Common Lisp - ĐH Bách Khoa TP.HCM

23 1,1K 2

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 23
Dung lượng 217,5 KB

Nội dung

BK TP.HCM ĐẠI HỌC BÁCH KHOA TPHCM KHOA CÔNG NGHỆ THÔNG TIN MÔN HỌC : NGÔN NGỮ LẬP TRÌNH LÝ THUYẾT VÀ BÀI TẬP THỰC HÀNH GOLDEN COMMON LISP TPHCM, Tháng 10 – 2004 LÝ THUYẾT VÀ BÀI TẬP THỰC HÀNH GOLDEN COMMON LISP Mục lục LÝ THUYẾT VÀ BÀI TẬP THỰC HÀNH GOLDEN COMMON LISP LÝ THUYẾT VÀ BÀI TẬP THỰC HÀNH GOLDEN COMMON LISP Mục lục Lý thuyết LISP I Giới thiệu II Cài đặt sử dụng gcLisp III Đặc điểm gcLisp IV Lập trình với gcLisp V Nâng cao 17 VI Tổng kết 20 Lý thuyết LISP I Giới thiệu - LISP – ngôn ngữ lập trình có tên lấy từ List Processing - Vào mùa hè năm 1956, Allen Newell, J.C Shaw, Herbert Simon phát triển xử lý Lisp (Lisp processing) tạo nên ngôn ngữ xử lý thông tin IPL (Information Processing Language) – ngôn ngữ trừu tượng thao tác symbols danh sách - Khi FORTRAN xây dựng, McCarthy thiết kế ngôn ngữ – LISP (Lisp Processor), lấy từ ý tưởng IPL, FORTRAN FLPL chạy IBM704 - Vào thập niên 70, Guy Steele Gerald Sussman định Scheme, kết hợp Algol Lisp - Vào đầu thập niên 80, có khoảng 12 hệ Lisp khác Các hệ Lisp không tương thích Do đó, dự án nhằm định ngôn ngữ Lisp chung hình thành – dự án kết hợp đặc tính tốt hệ Lisp thời vào thể thống - Phiên Common Lisp chuẩn đời năm 1984 – kết hợp nhiều ý tưởng ngôn ngữ lập trình thông dịch biên dịch hàm, dọn rác (garbage collection), gọi hàm đệ quy, theo vết dò lỗi (tracing and debugging) trình soạn thảo theo cú pháp II Cài đặt sử dụng gcLisp II.1 Cài đặt - Chép tập tin GC LISP.rar vào giải nén thư mục \GC LISP - Vào thư mục \GC LISP, chạy tập tin caidat.bat để cài gcLisp vào đĩa cứng - Vào thư mụcC:\Gclisp, chạy tập tin Gclisp.exe để bắt đầu II.2 Môi trường Gclisp Chúng ta thấy cửa sổ gclisp sau: Trang II.3 Phím nóng - -H to get help - -E to enter the LISP Explorer - -E to enter the editor - to exit editor into Lisp Environment - to load a file into the editor - to save a file - to save a file as another name II.4 Dòng lệnh Đánh dòng lệnh theo sau ký hiệu * II.5 Lệnh tiền tố (Prefix command) - Mọi lệnh nằm dấu ngoặc đơn ( ) - Lisp đánh giá đánh dấu ) cuối Trang (function ) - Lệnh có dạng tiền tố: II.6 - Load file vào gclisp Ví dụ: load first.lsp * (load ‘first) III Đặc điểm gcLisp III.1 Các đặc tính ngôn ngữ - Từ John McCarthy (MIT) nghĩ năm 1958, LISP tinh chế dần đến version 1.5 sử sụng lâu dài sau - Lisp ngôn ngữ hướng chức (functional language hay applicative), dùng lối ký hiệu tiền tố (prefix) dấu ngoặc đơn: f(x,y, z) ký hiệu (f x y z) Cũng x+y ký hiệu (+ x y) Bt - π  sin  x +  viết Lisp ? 2  ( sin ( + ( * x ) ( / pi 2) ) ) Lisp ngôn ngữ thông dịch (interpreted language) Ngôn ngữ biên dịch Ngôn ngữ thông dịch câu lệnh (instructions) Biểu thức biên dịch chương trình thực thi thực thi kết đánh giá trả lời Trang Kết Ví dụ: *(+ 4) *(+ (* 4)(- 2)) 15 *4 III.2 Kiểu liệu Lisp ngôn ngữ đặc trưng cho việc xử lý danh sách Chương trình biểu diễn danh sách thao tác liệu (+ (* 4) (- 2)) chương trình: hàm + áp dụng vào hai đối số liệu: danh sách gồm ba thành phần Ở top-level, đóng vai trò đối số hàm, danh sách xem áp dụng hàm Lisp thao tác loại liệu:  Biểu thức expression::= atom | list  Danh sách list::= (expression1 expressionn) Danh sách chuỗi biểu thức ngăn cách khoảng trắng, tất đặt dấu ngoặc đơn  Atoms atom::= số | chuỗi ký tự | symbols  Symbol (~ identifier): từ tạo ký tự bất kỳ, ngoại trừ ( khoảng trắng ) ‘ ` “ ;  Boolean: Lisp kiểu boolean Trong Lisp, nil mang giá trị logic sai tất biểu thức khác có giá trị Ký hiệu t dùng để trị logic theo mặc định Các kiểu liệu xếp theo cấp bậc sau: expression list atom Trang symbol list nil number interger real Biến Lisp kiểu liệu , biến có nhiều kiểu liệu khác Ví dụ: *(setq a ‘(1 3)) (1 3) *a (1 3) *(setq a 2) *a Kiểu gán cho liệu cho biến Ta biết kiểu liệu biến nhờ vào vị từ (prédicat) (numberp E) (stringp E) (listp E) (null E) (atom E) ;; ;; ;; ;; ;; trả trả trả trả trả về về đúng đúng nếu nếu E E E E E là là số chuỗi ký tự danh sách danh sách rỗng atom III.3 Vị từ (Prédicats)  Vị từ kiểu (xem phía trên)  Vị từ so sánh số: < > >= 5) NIL IV Lập trình với gcLisp IV.1 Các hàm xử lý danh sách IV.1.1 FIRST REST – CAR CDR  FIRST trả phần tử danh sách  REST trả danh sách theo sau phần tử Cho đến gần đây, phần lớn lập trình viên LISP dùng CAR CDR thay cho FIRST REST Ngoài chức tương tự, CAR CDR kết hợp với nhau.thành dạng phức hợp CxxR, CxxxR hay CxxxxR Mỗi x tượng trưng cho A – CAR hay D – CDR Trang Quy ước: *(car nil) NIL *(cdr nil) NIL Bài tập: Lấy phần tử thứ ba danh sách (car (cdr (cdr l))) viết: (caddr l) CAR CDR kết hợp với đến mức độ Ví dụ: (caadr l) = (car (car (cdr l))) (cadar l) = (car (cdr (car l))) Làm trích chuỗi example danh sách: L=((this) is (an (example)) more complex) L=((this) (cdr l) = (cdr (cdr (car (cdr (cdr (car (car (cdr (car (car is (an (example)) more complex) (is (an (example)) more complex) l)) = ((an (example)) more complex) (cdr l))) = (an (example)) (cdr (cdr l)))) = ((example)) (car (cdr (cdr l))))) = (example) (cdr (car (cdr (cdr l)))))) = example IV.1.2 CONS, APPEND, LIST  LIST trả danh sách đối số *(list ‘a (+ 1) ‘c) (a c) *(list ‘(a b) ‘(c d)) ((a b) (c d)) *(list ‘a nil) (a nil)  CONS thêm phần tử vào đầu danh sách (cons ‘a ‘(2 3)) (a 3) (cons `(a b) ‘(c d)) ((ab) c d) (list `a nil) (a) (CAR (CONS a l)) = a (CDR (CONS a l)) = l Trang Bt Cho biết giá trị biểu thức sau: (cons ‘a (cons ‘b (cons ‘c nil))) (cons ‘a (cons ‘b (cons ‘c nil))) = (cons ‘a (cons ‘b ‘(c))) = (cons ‘a ‘(b c)) = (a b c) (list (car ‘(car ((1) (2)))) (cdr (cdr ‘((1) (2))))) (list (car ‘(car ((1) (2)))) (cdr (cdr ‘((1) (2))))) = (list ‘car (cdr (cdr ‘((1) (2))))) = (list ‘car (cdr ((2)))) = (list ‘car nil) = (list ‘car nil) = (car nil)  APPEND kết hợp phần tử danh sách cho (setq l1 ‘(a b) l2 ‘(x y)) = (x y) (append l1 l2) = (a b x y) (append l1 ‘() l2 ‘()) = (a b x y) IV.1.3 NTHCDR, BUTLAST LAST  NTHCDR cắt n phần tử đầu danh sách, với thông số đầu số phần tử cần cắt *(setq l ‘(a b c d e)) (a b c d e) *(nthcdr l) (c d e)  BUTLAST cắt n phần tử cuối danh sách, với thông số đầu danh sách, thông số thứ hai số phần tử cần cắt *(setq l ‘(a b c d e)) (a b c d e) *(butlast l 2) (a b c) *(butlast l 10) NIL  LAST trả danh sách tất phần tử trừ phần tử cuối bị loại *(setq l ‘(a b c d e) l1 ‘((a b) (c d))) ((a b) (c d)) Trang *(last l) (e) *(last l1) ((c d)) IV.1.4 LENGTH REVERSE  LENGTH trả chiều dài chuỗi *(setq l ‘(a b c d e)) (a b c d e) *(length l)  REVERSE trả chuỗi nghịch đảo *(setq l ‘(a b c d e)) (a b c d e) *(reverse l) (e d c b a) IV.1.5 ASSOC  ASSOC gắn với danh sách – association list hay gọi a-list Key Key (setfl sarah ‘((height 54) (weight 4.4))) Value Value height weight khóa danh sách gán cho SARAH; 54 4.4 giá trị biểu thị met kilograms  Có thể lấy thành phần từ danh sách dùng ASSOC, khóa, danh sách liên kết: (ASSOC ) Ví dụ: (assoc ‘weight sarah) (WEIGHT 4.4) Lưu ý ASSOC trả toàn danh sách tương ứng với khóa Trong trường hợp có nhiều danh sách khóa, danh sách trả IV.1.6 LISP cung cấp thao tác Integer, Ratio, Floating-Point Numbers, *(/ 1.234321 1.111) 1.111 *(/ 27 9) Trang Tuy nhiên với trường hợp chia không chẵn, kết phân số: *(/ 22 7) 22/7 Dùng FLOAT muốn kết trả số thực có dấu phẩy động: (float (/ 22 7)) 3.14286 Dùng ROUND để làm tròn kết quả: *(round (/ 22 7)) 1/7 ;Thương – số nguyên gần ;Phần dư *(+ round (/ 22 7)) (round (7/3))) *(round (/ 2)) Một số hàm tính toán học: *(MAX 3) *(MIN 3) *(expt 3) *(expt 2) *(expt 3.3 2.2) 13.827085 *(sqrt 9) *(abs -5) IV.2 Các câu lệnh điều kiện  Câu lệnh IF (if E1 E2 E3) Nếu E1 đúng, trả giá trị E2 không trả giá trị E3 Ví dụ: *(if (numberp 1) ‘(a number) ‘(not a number)) (A NUMBER) *(if (numberp ‘a) ‘(a number) ‘(not a number)) (NOT A NUMBER)  AND (and E1 E2 En) sai Ei sai Trang AND đánh giá đối số từ trái sang phải dừng gặp đối số sai Nếu thông số đúng, and trả thông số cuối Ví dụ: *(setq x ‘a) A *x A *(and (numberp x) (> x 1) ) NIL *(and (symbolp x) (list x) ) (A)  OR (and E1 E2 En) sai Ei sai AND đánh giá đối số từ trái sang phải dừng gặp đối số Ví dụ: *(setq x ‘a) A *x A *(or (numberp x) (> x 1) ) error > A is not a number *(or (symbolp x) (list x) ) T IV.3 Định nghĩa hàm (defun ) Symbol đại diện cho biến biểu thức Ví dụ: *(defun square (x) (* x x)) SQUARE *(square 3) *(defun abs(x) (if (>= x 0) x (* -1 x) ) ) ABS Trang 10 IV.4 Chương trình đệ quy Lisp Vòng lặp Lisp thực chủ yếu nhờ vào đệ quy Ví dụ: Tính giai thừa n!=1*2* *n 0!=1 Trong Pascal, hàm n! viết vòng lặp: function fac(integer:n):integer; var i:integer begin fac:=1; for i:=1 to n fac:=fac*i; end Định nghĩa đệ quy giai thừa: n! = 1*2* *n-1 *n n!=n*(n-1) n≥2 (n-1)! 0!=1 Trong Lisp: (defun fac(n) (if (= n 0) (* n fac (1- n)) ) ) Bài tập: Viết hàm in phần tử thứ n danh sách (defun nth (if (= n (car (nth (n l) 1) l) (1- n) (cdr l)) ) ) Ví dụ đệ quy chéo hay lời gọi đệ quy: (defun pair (n) (or (= n 0) (impair (1- n)) ) ) (defun impair (n) (and ( n 0) (pair (1- n)) ) ) IV.5 Đánh giá ‘Exp cách viết tắt (quote Exp) *‘a A *‘‘a Trang 11 (QUOTE A) QUOTE không đánh giá đối số Ngược lại với quote hàm eval đánh giá giá trị đối số *(setq l ‘(a b c)) (A B C) *(eval (list ‘car ‘l)) A *(eval (list ‘* (1+ 3) 2)) Giá trị (eval ‘Exp) Exp IV.6 Các dạng đặc biệt (progn E1 En) đánh giá biểu thức E1, , En từ trái sang phải kết trả giá trị biểu thức En *(progn (setq x ‘(a b c)) (append x x) ) (A B C A B C) *(progn) NIL với defun if, kiểu progn tiềm ẩn n-airs (defun name(p1 … pm) E1 … En) (defun name(p1 … pm) (progn E1 … En)) (if Test E1 E2 … En) (if Test E1 (progn E2 … En)) điều không Clisp (prog1 E1 En) đánh giá biểu thức E1, , En từ trái sang phải kết trả giá trị biểu thức E1 *(prog1 (setq x ‘(a b c)) (append x x) ) (A B C) IV.7 Các trường hợp điều kiện (cond (Test1 E1 …) (Test2 E2 …) (Test3 E3 …) … (Testn En …) ) Trang 12 (if Test1 (progn E1 …) (if Test2 (progn E2 …) (if Test3 (progn E3 …) … (if Testn (progn En …)) … ) )) Trong mệnh đề kiểu (Test1), Test1 đúng, kết cond giá trị (Test1) Ví dụ: Viết hàm trả kiểu đối số *(type-of 1) FIXNUM *(type-of a) SYMBOL Giải: (defun type-of (x) (cond ((null x) ‘null) ((symbolp x) ‘symbolp) ((numberp x) ‘numberp) ((stringp x) ‘stringp) ((consp x) ‘consp) (t ‘unknown-type) ) ) IV.8 Biến cục (let ((var1 exp1) … (varm expm)) expm+1 … expn) Chúng ta gán cho biến giá trị biểu thức tương ứng, sau ta đánh giá (progn expm+1 … expn) Ví dụ: *(let ((x (fac 4))) (* x x)) = 576  Các biến cục che phủ biến toàn cục *(setq x 5) *(let ((x 1)) x) = *x *(let ((x 1)) (setq x 2) x) Trang 13 *x  Các biến cục che phủ đối số hàm *(defun foo(x) (let ((x 1)) x ) ) FOO *(foo 4)  Các liên kết thực song song *(defun bar(x) (let ((x 1) (y (1+ x))) y) ) BAR *(bar 4)  Dạng let* thực liên kết đối số *(defun bar(x) (let ((x 1) (y (1- x))) y) ) BAR *(defun bar1(x) (let* ((x 1) (y (1- x))) y) ) BAR *(bar 3) *(bar1 3)  let* tương ứng với let lồng * (defun bar(x) (let ((x 1)) (let ((y (1+ x))) y) ) ) BAR IV.9 Symbols  So sánh hai symbols Có thể so sánh hai symbols nhờ hàm eq *(eq ‘a ‘b) NIL *(eq ‘a ‘a) T Trang 14 (neq Exp) = (null (eq Exp))  Các trường symbol Symbol đối tượng bao gồm nhiều trường: CVAL: giá trị symbol biến PNAME: chuỗi ký tự tương ứng với tên symbol (dùng cho máy in)  FVAL: hàm gắn liền với symbol, trường không tồn LISP đơn trị LISP đa trị (bi-valued) LISP đơn trị (mono-valued) *(setq + 4) *(setq + 4) *(+ + 3) *(+ + 3) func + undef *(setq + *) *(* 3) = 12 var + indef  FTYPE: kiểu hàm  Ví dụ: * (setq foo 3) 3 CVAL *(defun foo(x) …) … FVAL EXPR FTYPE “foo” PNAME foo FOO IV.10 Lập trình hướng liệu  Ví dụ: Chúng ta muốn dùng hàm thực việc cộng hai số nối hai chuỗi  Giải pháp (defun add(x y) (cond ((numberp x) (+ x y)) ((listp x) (append x y) ) ) )  Giải pháp (putprop ‘add ‘+ ‘numberp) (putprop ‘add ‘append ‘listp) (defun add(x y) (funcall (getprop ‘add (type-of x)) x y) ) funcall cho phép gọi hàm tính toán Trang 15 IV.11 Lời gọi hàm tính toán  funcall: áp dụng giá trị thông số thứ (một hàm hay tên hàm) vào thông số (funcall ‘F E1…En) = (F E1…En) IV.12 Nhập/xuất  Có thể dễ dàng viết định nghĩa hàm file (có thể edit) sau load file lên load name tên hay đường dẫn đến file chứa định nghĩa hàm  (read) đọc biểu thức trả kết * (+ (read) 3) * = * (read) * (+ 4) = (+ 4) IV.13 Lưu ý  Có thể viết vòng lặp toplevel: (defun toplevel () (print (eval (read))) (toplevel) ) IV.14 Hiệu chỉnh  Đây ngôn ngữ tương tác (interactive), kiểm tra hàm toplevel mà không bắt buộc phải định nghĩa chương trình tests  Một kỹ thuật theo vết (trace) cho phép theo dõi trình thực hàm *(defun fac(n) (if (= n 0) (* n (fac (1- n))) ) ) FAC *(trace fac) ;Autoload: TRACE from “TRACE” in “C:\\GCLISP\\LISPLIB” T * (fac 2) ENTERING: FAC, ARGUMENT LIST: (2) ENTERING: FAC, ARGUMENT LIST: (1) ENTERING: FAC, ARGUMENT LIST: (0) EXITING: FAC, VALUE: EXITING: FAC, VALUE: EXITING: FAC, VALUE: 2  untrace cho phép trở thực bình thường hàm Trang 16 *(untrace fac) (FAC) *(fac 2)  trace cập nhật định nghĩa hàm theo vết cách in kết giai đoạn  theo dõi thực nhiều hàm lúc V Nâng cao V.1 V.1.1 Doublets Doublets  Một danh sách không rỗng biểu diễn đối tượng có hai trường gọi doublet trường trường car cdr phần lại phần tử đầu Tương tự vậy, danh sách (1 3) thể bởi: nil 3 Hay đơn giản hơn: V.1.2 nil Pointed pair  Thông số thứ hai cons không phảI danh sách Trong trường hợp đó, gọi cặp trỏ (pointed pair) *(cons ‘a ‘b) (A B) *(car ‘(a b)) A *(cdr ‘(a b)) B V.1.3 Ký hiệu pointed pair  Ký hiệu danh sách viết tắt ký hiệu pointed pair *‘(1 nil) Trang 17 (1) *‘(1 (2 (3 nil))) (1 3) Nói chung, có: (exp.(exp1 … expN))=(exp exp1 … expN)  Chúng ta kết hợp hai lối ký hiệu: *‘(1 (2 3)) (1 3) *‘(1 (2 3)) (1 3) V.1.4 Doublets  Mỗi biểu thức Lisp doublet hay atom expression ::= (expression.expression) | atom  Consp vị từ để kiểm tra thông số có doublet hay không (defun listp(p) (or (null x) (consp x) ) ) V.2 Apply  (apply F L) áp dụng hàm F phần tử danh sách L *(apply ‘append ‘((a b) (c d))) (a b c d) *(apply ‘+ ‘(1 2)) *(setq a ‘*) * *(apply a ‘(3 4)) 12  (apply F L) ≡ (eval (cons F L)) Bt Đếm số symbols, numbers hay strings list (defun count(test l) (if (null l) (if (apply test (list (car l))) (1+ (count test (cdr l))) (count test (cdr l)) ) ) ) V.3 Funcall ứng dụng  (apply f (list e1 … en)) ≈ (funcall f e1 … e2) *(setq a ‘+) + Trang 18 *(funcall a (+ 4) 5) 12 Lưu ý: Trong Lisp đơn trị (như Scheme), viết trực tiếp: * (a (+ 4) 5) = 12 có đánh giá hàm Bt Đếm số symbols, numbers hay strings list (defun count(test l) (if (null l) (if (funcall test (car l)) (1+ (count test (cdr l))) (count test (cdr l)) ) ) ) Bt Đếm số symbols, numbers hay strings list V.4 Lambda expression Dùng hàm count để đếm số số nguyên nhỏ 10 danh sách *(defun inf10(x) (and (integerp x) (< x 10)) ) INF10 *(count ‘inf10 ‘(4 12 a 11 3)) Nhận xét : Chúng ta định nghĩa hàm inf10 để sử dụng lần Có thể sử dụng hàm không tên Hàm Lisp gọi lambdaexpression va viết: (lambda header content) *(count (lambda (x) (and (integer x) (< x 10) ) ) ‘(4 12 a 11 3) Có thể trực tiếp định nghĩa lambda-expression xử lý: *(+ 10 ((lambda (x) (* x x)) 4) ) 26 V.5 Hàm vô danh biến cục Các biến cục bắt đầu với let tham số hàm vô danh (anonymous) (let ((var1 val1) … (varN valN)) corps) ≡ ( ( lambda (var1 … varN) corps) val1 … valN) *(let ((x 1) (y 2)) (+ x y)) * ( ( lambda (x y) (+ x y) ) ) Trang 19 VI Tổng kết Trang 20 [...]... x 0) x (* -1 x) ) ) ABS Trang 10 IV.4 Chương trình đệ quy trong Lisp Vòng lặp trong Lisp được thực hiện chủ yếu nhờ vào đệ quy Ví dụ: Tính giai thừa n!=1*2* *n 0!=1 Trong Pascal, hàm n! được viết bằng vòng lặp: function fac(integer:n):integer; var i:integer begin fac:=1; for i:=1 to n do fac:=fac*i; end Định nghĩa đệ quy của giai thừa: n! = 1*2* *n-1 *n n!=n*(n-1) nếu n≥2 (n-1)! 0!=1 Trong Lisp: (defun... không tồn tại trong LISP đơn trị LISP đa trị (bi-valued) LISP đơn trị (mono-valued) *(setq + 4) 4 *(setq + 4) 4 *(+ + 3) 7 *(+ + 3) func + undef *(setq + *) *(* 4 3) = 12 var + indef  FTYPE: kiểu hàm  Ví dụ: * (setq foo 3) 3 3 CVAL *(defun foo(x) …) … FVAL EXPR FTYPE “foo” PNAME foo FOO IV.10 Lập trình hướng dữ liệu  Ví dụ: Chúng ta muốn dùng cùng một hàm thực hiện việc cộng hai số và nối hai chuỗi... phải và kết quả trả về là giá trị của biểu thức En *(progn (setq x ‘(a b c)) (append x x) ) (A B C A B C) *(progn) NIL với defun và đôi khi if, kiểu progn tiềm ẩn và n-airs (defun name(p1 … pm) E1 … En) (defun name(p1 … pm) (progn E1 … En)) (if Test E1 E2 … En) (if Test E1 (progn E2 … En)) điều này không đúng trong Clisp (prog1 E1 En) đánh giá tuần tự các biểu thức E1, , En từ trái sang phải và kết... n!=n*(n-1) nếu n≥2 (n-1)! 0!=1 Trong Lisp: (defun fac(n) (if (= n 0) 1 (* n fac ( 1- n)) ) ) Bài tập: 1 Viết hàm in ra phần tử thứ n trong danh sách (defun nth (if (= n (car (nth (n l) 1) l) ( 1- n) (cdr l)) ) ) 2 Ví dụ đệ quy chéo hay lời gọi đệ quy: (defun pair (n) (or (= n 0) (impair ( 1- n)) ) ) (defun impair (n) (and ( n 0) (pair ( 1- n)) ) ) IV.5 Đánh giá ‘Exp là cách viết tắt của (quote Exp) *‘a A *‘‘a... bằng met và kilograms  Có thể lấy các thành phần từ một danh sách dùng ASSOC, một khóa, và danh sách liên kết: (ASSOC ) Ví dụ: (assoc ‘weight sarah) (WEIGHT 4.4) Lưu ý ASSOC luôn trả về toàn bộ danh sách con tương ứng với khóa Trong trường hợp có nhiều danh sách con cùng khóa, danh sách đầu tiên sẽ được trả về IV.1.6 LISP cung cấp các thao tác trên Integer, Ratio, Floating-Point... (Test1), nếu Test1 đúng, kết quả của cond là giá trị của (Test1) Ví dụ: Viết hàm trả về kiểu của đối số *(type-of 1) FIXNUM *(type-of a) SYMBOL Giải: (defun type-of (x) (cond ((null x) ‘null) ((symbolp x) ‘symbolp) ((numberp x) ‘numberp) ((stringp x) ‘stringp) ((consp x) ‘consp) (t ‘unknown-type) ) ) IV.8 Biến cục bộ (let ((var1 exp1) … (varm expm)) expm+1 … expn) Chúng ta gán cho mỗi biến giá trị... phủ các đối số của một hàm *(defun foo(x) (let ((x 1)) x ) ) FOO *(foo 4) 1  Các liên kết được thực hiện song song *(defun bar(x) (let ((x 1) (y (1+ x))) y) ) BAR *(bar 4) 5  Dạng let* thực hiện một liên kết tuần tự các đối số *(defun bar(x) (let ((x 1) (y ( 1- x))) y) ) BAR *(defun bar1(x) (let* ((x 1) (y ( 1- x))) y) ) BAR *(bar 3) 2 *(bar1 3) 0  let* tương ứng với let lồng nhau * (defun bar(x) (let... LENGTH và REVERSE  LENGTH trả về chiều dài của chuỗi *(setq l ‘(a b c d e)) (a b c d e) *(length l) 5  REVERSE trả về chuỗi nghịch đảo *(setq l ‘(a b c d e)) (a b c d e) *(reverse l) (e d c b a) IV.1.5 ASSOC  ASSOC gắn với một danh sách – association list hay còn gọi a-list Key Key (setfl sarah ‘((height 54) (weight 4.4))) Value Value height và weight là khóa trong danh sách được gán cho SARAH; 54 và. .. hiện một hàm *(defun fac(n) (if (= n 0) 1 (* n (fac ( 1- n))) ) ) FAC *(trace fac) ;Autoload: TRACE from “TRACE” in “C:\\GCLISP\\LISPLIB” T * (fac 2) ENTERING: FAC, ARGUMENT LIST: (2) ENTERING: FAC, ARGUMENT LIST: (1) ENTERING: FAC, ARGUMENT LIST: (0) EXITING: FAC, VALUE: 1 EXITING: FAC, VALUE: 1 EXITING: FAC, VALUE: 2 2  untrace cho phép trở về sự thực hiện bình thường của hàm Trang 16 *(untrace fac)... sử dụng một lần duy nhất Có thể sử dụng một hàm không tên Hàm như thế trong Lisp được gọi là lambdaexpression va được viết: (lambda header content) *(count (lambda (x) (and (integer x) (< x 10) ) ) ‘(4 12 a 11 3) 2 Có thể trực tiếp định nghĩa lambda-expression khi xử lý: *(+ 10 ((lambda (x) (* x x)) 4) ) 26 V.5 Hàm vô danh và biến cục bộ Các biến cục bộ được bắt đầu với let là các tham số của một hàm

Ngày đăng: 28/10/2015, 18:03

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w