Giáo trình Lập trình hàm và lập trình lôgic: Phần 1 - PGS.TS Phan Huy Khánh

20 16 0
Giáo trình Lập trình hàm và lập trình lôgic: Phần 1 - PGS.TS Phan Huy Khánh

Đ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

« Scheme demonstrate that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a pratical and efficient programming lang[r]

(1)

ĐẠI HỌC ĐÀ NẴNG

TRƯỜNG ĐẠI HỌC BÁCH KHOA

KHOA CÔNG NGH THÔNG TIN

G

GIIÁÁOO TTRRÌÌNNHH L

LPP TTRRÌÌNNHH HHÀÀMM V

VÀÀ LLPP TTRRÌÌNNHH LLƠƠGGIICC

PGS.TS PHAN HUY KHÁNH biên son

(2)

Mc lc

CHƯƠNG CÁC NGÔN NGỮ LẬP TRÌNH 5

I MỞĐẦUVỀNGƠNNGỮLẬPTRÌNH

I.1 Vài nét lịch sử

I.2 Định nghĩa ngơn ngữ lập trình

I.3 Khái niệm chương trình dịch

II PHÂNLOẠICÁCNGƠNNGỮLẬPTRÌNH

III NGƠNNGỮLẬPTRÌNHMỆNHLỆNH 11

IV CƠSỞCỦACÁCNGƠNNGỮHÀM 12

CHƯƠNG NGÔN NGỮ SCHEME 17

I GIỚITHIỆUSCHEME 17

II CÁCKIỂUDỮLIỆUCỦASCHEME 18

II.1 Các kiểu liệu đơn giản 18

II.1.1 Kiểu số 18

II.1.2 Kiểu lơgích vị từ 20

II.1.3 Ký hiệu 21

II.2 Khái niệm biểu thức tiền tố 23

II.3 S-biểu thức 24

III CÁCĐỊNHNGHĨATRONGSCHEME 25

III.1 Định nghĩa biến 25

III.2 Định nghĩa hàm 26

III.2.1 Khái niệm hàm Scheme 26

III.2.2 Gọi hàm sau định nghĩa 26

III.2.3 Sử dụng hàm bổ trợ 27

III.2.4 Tính khơng định kiểu Scheme 28

III.3 Cấu trúc điều khiển 29

III.3.1 Dạng điều kiện if 29

III.3.2 Biến cục 30

III.3.3 Định nghĩa vị từ 32

III.4 Sơđồđệ quy sơđồ lặp 33

III.4.1 Sơđồđệ quy 33

III.4.2 Ví dụ 34

III.4.3 Tính dừng lời gọi đệ quy 36

III.4.4 Chứng minh tính dừng 37

III.4.5 Sơđồ lặp 37

III.5 Vào/ra liệu 39

III.6 Kiểu liệu phức hợp 40

III.6.1 Kiểu chuỗi 40

III.6.2 Kiểu liệu vectơ 43

III.6.3 Khái niệm trừu tượng hoá liệu 43

III.6.4 Định nghĩa bộđôi 45

III.6.5 Đột biến bộđôi 47

III.6.6 Ứng dụng bộđôi 47

III.7 Kiểu liệu danh sách 52

(3)

III.7.3 Kỹ thuật đệ quy xử lý danh sách phẳng 64

III.7.4 Kỹ thuật đệ quy xử lý danh sách 67

III.8 Biểu diễn danh sách 70

III.8.1 Biểu diễn danh sách kiểu bộđôi 70

III.8.2 Danh sách kết hợp 73

III.8.3 Dạng quasiquote 76

III.9 Một số ví dụứng dụng danh sách 77

III.10 Sử dụng hàm 80

III.10.1 Dùng tên hàm làm tham đối 81

III.10.2 Áp dụng hàm cho phần tử danh sách 83

III.10.3 Kết trả hàm 85

III.11 Phép tính lambda 86

III.11.1 Giới thiệu phép tính lambda 86

III.11.2 Biễu diễn biểu thức lambda Scheme 87

III.11.3 Định nghĩa hàm nhờ lambda 88

III.11.4 Kỹ thuật sử dụng phối hợp lambda 90

III.11.5 Định nghĩa hàm nhờ tích luỹ kết 93

III.11.6 Tham đối hoá phần 95

III.11.7 Định nghĩa đệ quy cục 95

III.12 Xử lý hàm 97

III.12.1 Xây dựng phép lặp 97

III.12.2 Trao đổi thông điệp hàm 99

III.12.3 Tổ hợp hàm 101

III.12.4 Các hàm có số lượng tham đối 102

III.13 Một số ví dụ 104

III.13.1 Phương pháp xấp xỉ liên tiếp 104

III.13.2 Tạo thủ tục định dạng 105

III.13.3 Xử lý đa thức 106

III.13.4 Thuật toán quay lui 111

CHƯƠNG NGÔN NGỮ PROLOG 122

I GIỚITHIỆUNGƠNNGỮPROLOG 122

I.1 Prolog ngơn ngữ lập trình lơgich 122

I.1.1 Cú pháp Prolog 123

I.1.2 Các thuật ngữ 123

I.1.3 Các kiểu liệu Prolog 123

I.1.4 Chú thích 124

I.2 Các kiểu liệu sơ cấp Prolog 124

I.2.1 Kiểu số 124

I.2.2 Kiểu lôgich 125

I.2.3 Kiểu chuỗi ký tự 125

I.2.4 Kiểu nguyên tử 125

I.2.5 Biến 125

II SỰKIỆNVÀLUẬTTRONGPROLOG 125

II.1 Xây dựng kiện 125

II.2 Xây dựng luật 128

II.2.1 Định nghĩa luật 128

II.2.2 Định nghĩa luật đệ quy 132

II.2.3 Sử dụng biến Prolog 135

III KIỂUDỮLIỆUCẤUTRÚCCỦAPROLOG 136

III.1 Định nghĩa kiểu cấu trúc Prolog 136

(4)

IV QUANHỆGIỮAPROLOGVÀLƠGICHTỐNHỌC 141

IV.1 Các mức nghĩa chương trình Prolog 142

IV.2 Nghĩa khai báo chương trình Prolog 142

IV.3 Khái niệm gói mệnh đề 143

IV.4 Nghĩa lôgich mệnh đề 144

IV.5 Nghĩa thủ tục Prolog 145

IV.6 Tổ hợp yếu tố khai báo thủ tục 152

V VÍDỤ :CONKHỈVÀQUẢCHUỐI 153

V.1 Phát biểu toán 153

V.2 Giải toán với Prolog 154

V.3 Sắp đặt thứ tự mệnh đề đích 157

V.3.1 Nguy gặp vịng lặp vơ hạn 157

V.3.2 Thay đổi thứ tự mệnh đề đích chương trình 159

VI SỐHỌC 162

VI.1 Các phép toán số học 162

VI.2 Biểu thức số học 162

VI.3 Định nghĩa phép toán Prolog 164

VI.4 Các phép so sánh số học 168

VI.5 Các phép so sánh hạng 169

VI.6 Vị từ xác định kiểu 170

VI.7 Một số vị từ xử lý hạng 171

VII ĐỊNHNGHĨAHÀM 172

VII.1 Định nghĩa hàm sử dụng đệ quy 172

VII.2 Tối ưu phép đệ quy 179

VII.3 Một số ví dụ khác vềđệ quy 180

VII.3.1 Tìm đường đồ thị có định hướng 180

VII.3.2 Tính độ dài đường đồ thị 181

VII.3.3 Tính gần chuỗi 181

VIII BIỂUDIỄNCẤUTRÚCDANHSÁCH 182

IX MỘTSỐVỊTỪXỬLÝDANHSÁCHCỦAPROLOG 184

X CÁCTHAOTÁCCƠBẢNTRÊNDANHSÁCH 185

X.1 Xây dựng lại số vị từ có sẵn 185

X.1.1 Kiểm tra phần tử có mặt danh sách 185

X.1.2 Ghép hai danh sách 186

X.1.3 Bổ sung phần tử vào danh sách 189

X.1.4 Loại bỏ phần tử khỏi danh sách 189

X.1.5 Nghịch đảo danh sách 190

X.1.6 Danh sách 190

X.1.7 Hoán vị 191

X.2 Một số ví dụ danh sách 192

X.2.1 Sắp xếp phần tử danh sách 192

X.2.2 Tính độ dài danh sách 193

(5)

CHƯƠNG

CÁC NGƠN NG LP TRÌNH

I. Mở đầu về ngơn ngữ lập trình

I.1. Vài nét về lịch sử

Buổi ban đầu

hững ngơn ngữ lập trình (programming language) máy tính điện tử ngơn ngữ máy (machine language), tổ hợp số hệ hai, hay hệ nhị phân, hay bit

(viết tắt binary digit) Ngôn ngữ máy phụ thuộc hồn tồn vào kiến trúc phần cứng máy tính quy ước khắt khe nhà chế tạo Để giải tốn, người lập trình phải sử dụng tập hợp lệnh điều khiển sơ cấp mà lệnh tổ hợp số

hệ hai nên gặp nhiều khó khăn, mệt nhọc, dễ mắc phải sai sót, lại khó sửa lỗi Từ năm 1950, để giảm nhẹ việc lập trình, người ta đưa vào kỹ thuật chương trình con (sub-program hay sub-routine) xây dựng thư viện chương trình (library) để cần gọi đến dùng lại đoạn chương trình viết

Ngôn ngữ máy tiến gần đến ngôn ngữ tự nhiên

Cũng từ năm 1950, ngôn ngữhợp dịch, hay hợpngữ(assembly) hay cịn gọi ngơn ngữbiểu tượng (symbolic) đời Trong hợp ngữ, mã lệnh địa toán hạng thay từ tiếng Anh gợi nhớ (mnemonic) ADD, SUB, MUL, DIV, JUMP tương ứng với phép tốn số học + - × /, phép chuyển điều khiển, v.v

Do máy tính hiểu ngơn ngữ máy, chương trình viết hợp ngữkhơng thể chạy mà phải qua giai đoạn hợp dịch (assembler) thành ngôn ngữ máy Tuy nhiên, hợp ngữ phụ thuộc vào phần cứng xa lạ với ngơn ngữ tự nhiên (natural language), người lập trình cịn gặp nhiều khó khăn giải tốn máy tính

Năm 1957, hãng IBM đưa ngôn ngữ FORTRAN (FORmula TRANslator) Đây ngôn ngữ lập trình gần gũi ngơn ngữ tự nhiên với cách diễn đạt toán học FORTRAN cho phép giải nhiều loại toán khoa học, kỹ thuật sau nhanh chóng ứng dụng rộng rãi ngày với kho tàng thư viện thuật toán đồ sộ tiện dụng Tiếp theo đời ngôn ngữ ALGOL 60 (ALGOrithmic Language) năm 1960, COBOL (Comon Business Oriented Language) năm 1964, Simula năm 1964, v.v

Phát triển ngôn ngữ lập trình

Theo phát triển hệ máy tính, ngơn ngữ lập trình khơng ngừng cải tiến hồn thiện để ngày đáp ứng nhu cầu người sử dụng giảm nhẹ cơng việc lập trình Rất nhiều ngơn ngữ lập trình đời tảng lý thuyết tính tốn (theory of computation) hình thành hai loại ngôn ngữ : ngôn ngữ bậc thấp ngôn ngữ bậc cao

Các ngôn ngữbậc thấp (low-level language), hợp ngữ ngôn ngữ máy, thường dùng

để viết chương trình điều khiển kiểm tra thiết bị, chương trình sửa lỗi (debugger) hay cơng cụ

(6)

Các ngôn ngữ lập trình bậc cao (high-level language) phương tiện giúp người làm tin học giải vấn đề thực tế đồng thời nơi mà thành tựu nghiên cứu khoa học máy tính đưa vào Lĩnh vực nghiên cứu phát triển ngôn ngữ

lập trình vừa có tính truyền thống, vừa có tính đại Ngày nay, với tiến khoa học cơng nghệ, người ta sử dụng cơng cụ hình thức cho phép giảm nhẹ cơng việc lập trình từ lúc phân tích, thiết kế sử dụng ngơn ngữ lập trình

I.2. Định nghĩa một ngơn ngữ lập trình

Các ngơn ngữ lập trình bậc cao xây dựng mô ngôn ngữ tự nhiên, thường tiếng Anh (hoặc tiếng Nga năm trước đây) Định nghĩa ngơn ngữ lập trình định nghĩa văn phạm (grammar) để sinh câu ngôn ngữ Có thể hình dung văn phạm gồm bốn thành phần : bộ ký tự, từ vựng, cú pháp ngữ nghĩa.

1 Bộ ký tự(character set)

Gồm số hữu hạn ký tự (hay ký hiệu) phép dùng ngôn ngữ Trong máy tính cá nhân, người ta thường sử dụng ký tự ASCII Có thể hiểu ký tự có vai trị bảng chữ (alphabet) ngôn ngữ tự nhiên để tạo từ (word)

2 Bộ từ vụng (vocabulary)

Gồm tập hợp từ, hay đơn vị từ vựng (token), xây dựng từ ký tự Các từ

dùng để tạo thành câu lệnh chương trình phân loại tuỳ theo vai trò chức chúng ngơn ngữ Chẳng hạn chương trình Pascal sau :

program P;

var ×, y : integer; begin

read(x); y:=x+2; write(y) end

gồm đơn vị từ vựng :

Từ khoá (keyword), hay từ dành riêng (reserved word) : program, var, integer, begin, end

Tên, hay định danh (identifier) : read, write, P, x, y Hằng (constants) :

Phép toán (operators) : + , :=

Dấu phân cách (delimiters) : :, (, ),

3 Cú pháp (syntax)

Cú pháp quy định cách thức kết hợp ký tự thành từ, kết hợp từ thành câu lệnh (statement hay instruction), kết hợp câu lệnh thành chương trình hồn chỉnh

mặt văn phạm Có thể hình dung cách kết hợp giống cách đặt câu ngôn ngữ tự

(7)

Ví dụ I.1 : Trong ngơn ngữ Pascal (hoặc phần lớn ngôn ngữ lập trình), tên gọi, hay

định danh (identifier) có sơđồ cú pháp sau :

Hình 0.1 Sơđồ cú pháp tên ngôn ngữ Pascal

Trong sơđồ cú pháp, hình chữ nhật phải thay hình trịn Quá trình thay thực thứ tự theo chiều mũi tên nhận câu Chẳng hạn «đọc» sơđồ sau : tên phải bắt đầu chữ, chữ

hoặc số tuỳ ý, chữ chũ A Za z, số chũ số Như vậy, Delta, x1, x2, Read, v.v tên viết đúng, cịn 1A, β, π, bán kính, v.v khơng phải tên vi phạm quy tắc cú pháp

Văn phạm BNF gồm dãy quy tắcc Mỗi quy tắc gồm vế trái, dấu định nghĩa ::= (đọc

được định nghĩa bởi) vế phải Vế trái ký hiệu phải định nghĩa, vế phải dãy ký hiệu, thừa nhận, định nghĩa từ trước đó, tuân theo quy ước EBNF dùng ký tự quy ước sau :

Ký hiệu Ý nghĩa

::=, →, = định nghĩa

{ } chuỗi hay nhiều mục liệt kê tuỳ chọn (option) [] hoặc mục liệt kê tuỳ chọn

< > mục liệt kê phải thay

| (theo nghĩa loại trừ) Các quy tắc BNF định nghĩa tên ngôn ngữ Pascal : <tên> ::= <chữ> { <chữ> | <số> }

<chữ> ::= ’A’ | | ’Z’ | ’a’ | | ’z’ <số> ::= ’0’ | | ’9’

Ví dụ I.2

Văn phạm ngôn ngữ lập trình đơn giản dạng EBNF sau : <program> ::= program <statement>* end

<statement> ::= <assignment> | <loop>

<assignment> ::= <identifier> := <expression> ; <loop> ::=

while <expression> do <statement>+ done <expression> ::=

<value> | <value> + <value> | <value> <= <value> <value> ::= <identifier> | <number>

<identifier> ::=

<letter>|<identifier><letter>|<identifier><digit> <number> ::= <digit> | <number><digit>

<letter> ::= ’A’ | | ’Z’ | ’a’ | | ’z’ <digit> ::= ’0’ | | ’9’

tên

chữ

số

chữ

chữ

A Z a z

số

(8)

Một câu, tức chương trình đơn giản, viết văn phạm sau : program

n := 1 ;

while n <= 10 do n := n + 1 ; done end

4 Ngữ nghĩa (semantic)

Căn vào cú pháp ngôn ngữ lập trình, người lập trình viết chương trình gồm câu lệnh theo trình tự cho phép để giải tốn Để đạt mục đích đó, câu lệnh viết đắn mặt cú pháp, mà phải đắn mặt ngữ nghĩa, hay ý nghĩa logic câu lệnh Tính đắn mặt ngữ nghĩa cho phép giải tốn, chương trình chạy ln ln dừng, ổn định cho kết phù hợp với yêu cầu đặt ban đầu

I.3. Khái niệm về chương trình dịch

Chương trình viết ngơn ngữ lập trình bậc cao, hợp ngữ,

được gọi chương trình nguồn (source program)

Bản thân máy tính khơng hiểu câu lệnh chương trình nguồn Chương trình nguồn phải dịch (translate) thành một chương trình đích (target program) ngôn ngữ máy (là dãy số0 1), máy có thểđọc «hiểu» thực Chương trình đích cịn gọi chương trình thực hiện (executable program)

Chương trình trung gian đảm nhiệm việc dịch gọi chương trình dịch

Việc thiết kế chương trình dịch cho ngơn ngữ lập trình cho khó khăn phức tạp Chương trình dịch nguyên tắc phải viết ngôn ngữ máy để giải vấn đề

xử lý ngơn ngữ tính vạn chương trình nguồn Tuy nhiên, người ta thường sử

dụng hợp ngữ để viết chương trình dịch Bởi việc dịch chương trình hợp ngữ ngôn ngữ máy đơn giản nhiều Hiện nay, người ta viết chương trình dịch ngôn ngữ bậc cao công cụ chuyên dụng

Thơng thường có hai loại chương trình dịch, hay hai chếđộ dịch, trình biên dịch trình thơng dịch, hoạt động sau :

Trình biên dịch (compilater) dịch tồn chương trình nguồn thành chương trình đích sau bắt đầu tiến hành thực chương trình đích

Trình thơng dịch (interpreter) dịch câu lệnh chương trình nguồn tiến hành thực câu lệnh dịch đó, thực xong tồn chương trình

Có thể hiểu trình biên dịch dịch giả, trình thơng dịch thơng dịch viên

(9)

II. Phân loại ngơn ngữ lập trình

Cho đến nay, có hàng trăm ngơn ngữ lập trình đề xuất thực tế, có số ngơn ngữđược sử dụng rộng rãi Ngồi cách phân loại theo bậc nói trên, người ta cịn phân loại ngơn ngữ lập trình theo phương thức (paradigm), theo mức độ quan trọng (measure of emphasis), theo thế hệ (generation), v.v

Cách phân loại theo bậc hay mức (level) dựa mức độ trừu tượng so với yếu tố

phần cứng, chẳng hạn nhưlệnh (instructions) cấp phát nhớ (memory allocation)

Mức Lệnh Sử dụng nhớ Ví dụ

Thấp Lệnh máy đơn giản Truy cập cấp phát trực tiếp Hợp ngữ, Autocode Cao Biểu thức điều khiển

tường minh

Truy cập cấp phát nhờ phép toán, chẳng hạn new

FORTRAN, ALGOL, Pascal, C, Ada

Rất cao Máy trừu tượng Truy cập ẩn tựđộng cấp phát SELT, Prolog, Miranda

Hình 0.2 Ba mức ngơn ngữ lập trình.

Những năm gần đây, ngơn ngữ lập trình phát triển theo phương thức lập trình (cịn gọi phong cách hay kiểu lập trình) Một phương thức lập trình có thểđược hiểu tập hợp tính trừu tượng (abstract features) đặc trưng cho lớp ngơn ngữ mà có nhiều người lập trình thường xuyên sử dụng chúng Sơđồ sau minh hoạ phân cấp phương thức lập trình :

Hình 0.3 Phân cấp phương thức lập trình

Sau số ngơn ngữ lập trình quen thuộc liệt kê theo phương thức :

Các ngơn ngữmệnh lệnh (imperative) có Fortran (1957), Cobol (1959), Basic (1965), Pascal (1970), C (1971), Ada (1979)

Các ngôn ngữđịnh hướng đối tượng (object-oriented)có Smalltalk (1969), C++ (1983), Eiffel (1986), Java (1991), C# (2000),

Các ngơn ngữ hàm (functional) có Lisp (1958), ML (1973), Scheme (1975), Caml (1987), Miranda (1982),

Các ngôn ngữdựa logic (logic-based) chủ yếu ngôn ngữ Prolog (1970) Ngôn ngữ thao tác sở liệu SQL (1980)

Các ngôn ngữ xử lý song song (parallel) Ada, Occam (1982), C-Linda, Ngồi cịn có số phương thức lập trình phát triển ứng dụng :

Lập trình phân bổ (distributed programming)

Lập trình ràng buộc (constraint programming)

Lập trình hướng truy cập (access-oriented programming)

Thủ tục đốHi tướượng ng song songXử lý Lôgic Hàm dCữơ li sệởu Mệnh lệnh

Phương thức lập trình

(10)

Lập trình theo luồng liệu (dataflow programming), v.v

Việc phân loại ngơn ngữ lập trình theo mức độ quan trọng dựa cái gì (what)

thao tác (achieved), hay tính (computed), so với cách thao tác như nào (how) Một ngôn ngữ thể thao tác mà khơng cách thao tác gọi ngôn ngữ định nghĩa (definitional) hay khai báo (declarative) Một ngôn ngữ thể cách thao tác mà khơng thao tác gọi ngôn ngữ thao tác

(operational) hay không khai báo (non-declarative), ngơn ngữ mệnh lệnh.

Hình 0.4 Phát triển ngơn ngữ lập trình

Các ngơn ngữ lập trình phân loại theo hệ sau : Thế hệ : ngôn ngữ máy

Thế hệ : hợp ngữ

Thế hệ : ngôn ngữ thủ tục

Thế hệ : ngôn ngữ áp dụng hay hàm Thế hệ : ngôn ngữ suy diễn hay dựa logic Thế hệ : mạng nơ-ron (neural networks)

(11)

III. Ngơn ngữ lập trình mệnh lệnh

Trong ngôn ngữ mệnh lệnh, người lập trình phải tìm cách diễn đạt thuật tốn, cho biết làm cách nào để giải toán cho Mơ hình tính tốn sử dụng tập hợp (hữu hạn) trạng thái thay đổi trạng thái Mỗi trạng thái phản ánh nội dung biến liệu

đã khai báo Trạng thái bị thay đổi lệnh điều khiển lệnh gán giá trị cho biến chương trình Chương trình biên dịch cho phép lưu giữ trạng thái

nhớ ghi, chuyển phép toán thay đổi trạng thái thành lệnh máy để

thực

Hình 0.5 Quan hệ tên biến, kiểu giá trị ngơn ngữ mệnh lệnh

Hình 0.5 minh họa cách khai báo liệu ngôn ngữ mệnh lệnh mối quan hệ theo mức Người ta phân biệt ba mức sau : mức ngôn ngữ liên quan đến tên biến, tên kiểu liệu cấu trúc lưu trữ ; mức chương trình dịch liên quan đến phương pháp tổ chức

nhớ mức máy cho biết cách biểu diễn theo bit giá trị liệu tương ứng Mỗi khai báo biến, ví dụint i, nối kết (bind) tên biến (i) với cấu trúc đặc trưng tên kiểu (int) với giá trị liệu biểu diễn theo bit nhờ lệnh gán i := 5 (hoặc nhờ lệnh vừa khai báo vừa khởi gán int i=5) Tổ hợp tên, kiểu giá trịđã tạo nên đặc trưng biến

Các ngôn ngữ mệnh lệnh sử dụng hiệu lập trình người lập trình

tác động trực tiếp vào phần cứng Tuy nhiên, tính thực dụng mệnh lệnh làm hạn chế trí tuệ người lập trình phải phụ thuộc vào cấu trúc vật lý máy tính Người lập trình ln có khuynh hướng suy nghĩ vị trí lưu trữ liệu đặt tên (nguyên tắc địa hoá) mà nội dung chúng thường xuyên bị thay đổi Thực tế có nhiều toán cần trừu tượng hoá giải (nghĩa không phụ thuộc vào cấu trúc vật lý máy tính), khơng địi hỏi tính thành thạo người lập trình, mà cịn địi hỏi kiến thức Tốn học tốt khả trừu tượng hoá họ

Từ lý mà người ta tìm cách phát triển mơ hình tương tác khơng phản ánh mối quan hệ với phần cứng máy tính, mà làm dễ dàng lập trình Ý tưởng mơ hình người lập trình cần đặc tả tính tốn mà khơng phải mơ tả cách tính

nào Sự khác «như nào» «cái gì», khác ngôn ngữ

mệnh lệnh ngôn ngữ khai báo, luôn rõ ràng Các ngơn ngữ khai báo thường khó cài đặt khó vận hành ngôn ngữ mệnh lệnh Các ngôn ngữ mệnh lệnh thường gần gũi người lập trình

Sau sốđặc trưng ngôn ngữ lập trình mệnh lệnh :

− Sử dụng nguyên lý tinh chế bước hay làm mịn dần, xử lý đối tượng

liệu đặt tên

Kiểu :

tập hợp giá trị

tập hợp phép toán cấu trúc lưu trữ

bit

dấu 214 213 22

21 20 biểu diễn theo bit :

0 0 1 ., −1, 0, 1,

+, −, ×, /,

Mức ngơn ngữ

Mức chương

trình dịch

Mức máy

Số

5

Tên kiểu

integer

Tên biến

(12)

− Khai báo liệu để nối kết tên biến khai báo với kiểu liệu giá trị Phạm vi hoạt động (scope) biến chương trình xác định khai báo, toàn cục (global), cục (local)

− Các kiểu liệu thông dụng số nguyên, số thực, ký tự lôgic Các kiểu

được xây dựng nhờ kiểu cấu trúc Ví dụ kiểu mảng, kiểu ghi, kiểu tập hợp, kiểu liệt kê,

− Hai kiểu liệu có tên tương đương với nhau, hai cấu trúc liệu tương

đương có giá trị có phép tốn xử lý

− Trạng thái (bộ nhớ ghi) bị thay đổi lệnh gán Trạng thái (thiết bị ngoại vi) bị thay đổi lệnh vào-ra Giá trịđược tính từ biểu thức

− Các cấu trúc điều khiển tuần tự, chọn lựa (rẽ nhánh), lặp gọi chương trình

− Chương trình thường có hai dạng : dạng thủ tục (procedure) dạng hàm (function) Sự khác chủ yếu hàm trả giá trị, cịn thủ tục khơng khơng thiết trả giá trị Việc trao đổi tham biến (parameter passing) với chương trình theo trị (by value) theo tham chiếu (by reference)

− Sử dụng chương trình thường gây hiệu ứng phụ (side effect) làm thay

đổi biến tồn cục

− Một chương trình xây dựng theo bốn mức : khối (block), chương trinh con, đơn thể(module/packages) chương trình

IV. Cơ sở của ngơn ngữ hàm

Trong ngôn ngữ mệnh lệnh, chương trình thường chứa ba lời gọi chương trình (thủ tục, hàm) liên quan đến trình đưa vào liệu, xử lý liệu đưa kết tính tốn sau :

begin

GetDată ) ; { đưa vào } ProcessDatặ ); { xử lý }

OutPutResults( ); { xem kết } end

Trong ngơn ngữ lập trình hàm, lời gọi chương trình viết thành biểu thức đơn giản :

(print

(process-data

(get-data ( ))))

Các ngôn ngữ hàm ngơn ngữ bậc cao, mang tính trừu tượng so với ngôn ngữ mệnh lệnh

Những người lập trình hàm thường tránh sử dụng biến tồn cục, đó, hầu hết người lập trình mệnh lệnh phải sử dụng đến biến tồn cục

Khi lập trình với ngơn ngữ hàm, người lập trình phải định nghĩa hàm tốn học dễ

suy luận, dễ hiểu mà không cần quan tâm chúng cài đặt máy

Những người theo khuynh hướng lập trình hàm cho lệnh chương trình viết ngơn ngữ mệnh lệnh làm thay đổi trạng thái toàn cục hồn tồn bất lợi Bởi nhiều phần khác chương trình (chẳng hạn hàm, thủ tục) tác động không trực tiếp lên biến làm chương trình khó hiểu Các thủ tục thường gọi sử dụng

(13)

(correctness proof), cản trở tối ưu hóa (optimization), cản trở trình song song tự động (automatic parrallelization) chương trình

Một ngơn ngữ hàm, hay ngơn ngữ áp dụng (applicative language) dựa việc tính giá trị

của biểu thức xây dựng từ bên ngồi lời gọi hàm Ởđây, hàm hàm tốn học túy : ánh xạ nhận giá trị lấy từ miền xác định (domain) để trả giá trị

thuộc miền khác (range hay co-domain)

Một hàm có, khơng có, tham đối (arguments hay parameters) để sau tính tốn, hàm trả giá trị Chẳng hạn xem biểu thức + hàm tính tổng (phép +) hai tham đối

Ta thấy hàm không gây hiệu ứng phụ trạng thái chương trình, trạng thái trì cho tham đối hàm Tính chất đóng vai trị quan trọng lập trình hàm Đó kết hàm không phụ vào thi đim (when) hàm

được gọi, mà phụ thuộc vào cách gi tham đối.

Trong ngơn ngữ lập trình mệnh lệnh, kết biểu thức : f(x) + f(x)

có thể khác với kết : * f(x)

vì lời gọi f(x) làm thay đổi x biến tiếp cận f Trong ngơn ngữ lập trình hàm, hai biểu thức ln có giá trị

Do hàm không phụ thuộc nhiều vào biến tồn cục, nên việc lập trình hàm dễ

hiểu lập trình mệnh lệnh Ví dụ giả sử trình biên dịch cần tối ưu phép tính : f(x) + f(x)

thành :

2 * f(x)

Khi đó, trình biên dịch ngơn ngữ hàm luôn xem hai kết một, có tính qn kết trả hàm Tuy nhiên, trình biên dịch ngơn ngữ mệnh lệnh, ngơn ngữ Ada1 chẳng hạn, phải chứng minh kết lời gọi thứ hai không phụ thuộc vào biến bị thay đổi trình thực lời gọi thứ

Một trình biên dịch song song gặp phải vấn đề tương tự trình muốn gọi hàm theo kiểu gọi song song

Bên cạnh tính ưu việt, ta cần xem xét bất lợi vốn có lập trình hàm : nhược

điểm ngôn ngữ hàm thiếu lệnh gán biến tồn cục, khó khăn việc mơ tả cấu trúc liệu khó thực trình vào/ra liệu

Tuy nhiên, ta thấy thiếu lệnh gán biến toàn cục khơng ảnh hưởng hay khơng làm khó khăn nhiều cho việc lập trình Khi cần, lệnh gán giá trị cho biến mô cách sử dụng cấu tham biến hàm, chương trình viết ngơn ngữ mệnh lệnh

Chẳng hạn ta xét hàm P sử dụng biến cục bộx trả giá trị có kiểu

nào (SomeType) Trong ngơn ngữ mệnh lệnh, hàm P làm thay đổi x gán cho x

môt giá trị Trong ngơn ngữ hàm, P mơ thay đổi truyền giá trị

1

(14)

mới x tham đối cho hàm phụ trợ thực phần mã lại P Chẳng hạn, thay đổi giá trị biến chương trình P :

function P(n: integer) −> SomeType ; x: integer := n +

begin

x := x * + return * g(x) end ;

ta viết lại sau :

function P(n : integer) −> SomeType ; x: integer := n +

begin

return Q(3*x + 1) % mô x := x * + end ;

trong đó, hàm Qđược định nghĩa sau :

function Q(x: integer) −> Some Type begin

return * g(x) end ;

Ta sử dụng kỹ thuật cho biến tồn cục Như vậy, việc mơ lập trình mệnh lệnh ngôn ngữ hàm cách mong muốn, làm

được

Một vấn để bật ngôn ngữ hàm thay đổi cấu trúc liệu Trong ngôn ngữ mệnh lệnh, thay đổi phần tử mảng đơn giản Trong ngôn ngữ hàm, mảng bị thay đổi Người ta phải chép mảng, trừ phần tử bị thay đổi, thay giá trị cho phần tử Cách tiếp cận hiệu so với phép gán cho phần tử

Một vấn đề khác lập trình hàm khả hạn chế giao tiếp hệ thống tương tác với hệđiều hành với người sử dụng Tuy nhiên nay, người ta có xu hướng tăng cường thư viện hàm mẫu xử lý hướng đối tượng giao diện đồ hoạ (GUI-Graphic User Interface) Chẳng hạn phiên thông dịch họ Lisp DrScheme, MITScheme, WinScheme

(15)

Bài tp chương : ÔN LI THUT TỐN Tính gần giá trị hàm sau với độ xác e = 10-5

π 1

= − + − +

2n -1 <ε

2

x x x

1 + + + +

2 3× 5× × phần tử thứn < e S = - x + x

2! - x

3! + + (-1) x

n! +

2

n n cho đến xn

n! <ε

S x x x x n

n

= +1 + + + + +

2

2

! ! ! ( )!

x n n 10 ( )! <

y = x + x + + x có n > dấu

2 Tìm ước số chung lớn * số nguyên p, q

3 Cho danh sách số nguyên L số nguyên K, thực việc sau : a)Đếm số chia hết cho K L ?

b)Kiểm tra sốK có nằm danh sách L hay khơng ? c)Cho biết vị trí phần tửđầu tiên danh sách L K ? d)Tìm tất vị trí phần tử K danh sách L ? e)Thay phần tử K danh sách L phần tửK’ cho ?

4 Viết chương trình để xóa ba phần tửđầu tiên ba phần tử cuối danh sách Viết chương trình để xóa N phần tử danh sách Thất bại danh sách

khơng có đủ N phần tử

6 Viết chương trình để xóa N phần tử cuối danh sách Thất bại danh sách khơng có đủ N phần tử

7 Định nghĩa hai hàm even_length odd_length để kiểm tra số phân tử danh sách cho chẵn hay lẻ tương ứng

Ví dụ danh sách [a, b, c, d ] có độ dài chẵn, danh sách [ a, b, c ] có độ dài lẻ

Viết chương trình kiểm tra danh sách có phải tập hợp danh sách khác không ?

8 Viết chương trình để lấy phần tử thứ N danh sách Thất bại danh sách khơng có đủ N phần tử

Viết chương trình tìm phần tử lớn phần tử nhỏ danh sách số Viết chương trình để kiểm tra hai danh sách có rời (disjoint) không ?

(16)

luôn thỏa mãn lần chuyển đĩa từ cọc sang cọc khác, cọc đĩa sau nhỏ chồng lên đĩa trước lớn đĩa lớn

11.Viết chương trình để tạo số nguyên tố sử dụng sàng Eratosthènes Chương trình khơng kết thúc Thử sử dụng kỹ thuật tính giá trị hàm theo kiểu khơn ngoan để có lời giải đơn giản hiệu

12.Cây nhị phân (binary tree) biểu diễn một danh sách gồm ba phần tử

liệu : nút gốc (root node), bên trái (left subtree) bên phải (right subtree) nút gốc Mỗi lại xem nhị phân Cây, rỗng (empty tree) biểu diễn danh sách rỗng Ví dụ cho nhị phân có nút [1, [2, [], []], [3, [4, [], []], []]] sau :

Hình 0.6 Cây nhị phân có nút

Viết chương trình duyệt theo thứ tự (trái-gốc-phải), trước (gốc-trái-phải) sau (trái- phải-gốc) ?

1

2

(17)

CHƯƠNG

NGÔN NG SCHEME

A line may take us hours, yet if it does not seem a moment's thought All our stitching and unstitching has been as nought

Yeats - Adam's Curse

I. Giới thiệu Scheme

cheme ngôn ngữ thao tác ký hiệu (symbolic manipulation) Guy Lewis Steele Jr Gerald Jay Sussman đề xuất năm 1975 MIT (Massachusetts Institute of Technology, Hoa Kỳ), sau phát triển nhanh chóng ứng dụng phổ biến Scheme ngôn ngữ thuộc họ Lisp mang tính sư phạm cao Scheme giải thích hợp toán toán học xử lý ký hiệu Theo W Clinger J Rees2 :

«Scheme demonstrate that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a pratical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today »

Tương tự ngơn ngữ hàm khác, Scheme có cú pháp đơn giản nên dễ lập trình Các cấu trúc liệu sở Scheme danh sách cây, dựa khái niệm vềkiểu liệu trừu tượng (data abstraction type) Một chương trình Scheme dãy định nghĩa hàm (hay

thủ tục) góp lại để định nghĩa nhiều hàm phức tạp Hoạt động lập trình Scheme tính giá trị biểu thức Scheme làm việc theo chếđộ tương tác (interaction) với người sử dụng

Mỗi vòng tương tác xảy sau :

Người sử dụng gõ vào biểu thức, sau dòng nhấn enter (↵) Hệ thống in kết (hoặc báo lỗi) qua dòng

Hệ thống đưa dấu nhắc (prompt character) chờ người sử dụng đưa vào biểu thức

Việc lựa chọn dấu nhắc tùy theo quy ước hệ thống, thông thường dấu lớn (>) dấu hỏi (?)3

Một dãy phép tính giá trị biểu thức vịng tương tác gọi chầu làm việc (session) Sau chầu, Scheme đưa thời gian số lượng nhớ (bytes) sử dụng

để tính tốn

Để tiện theo dõi, sách sử dụng quy ước sau : Kết tính tốn ghi theo sau dấu mũi tên ( >) Các thông báo lỗi sai đặt trước ba dấu (***)

Cú pháp biểu thức viết theo quy ước EBNF kiểu chữ nghiêng đậm Ví dụ : <e>

2Xem tài liệu định nghĩa ngôn ngữ Scheme tại địa chỉhttp://www.swiss.ai.mit.edu/~jaffer/r5rs_toc.html 3

(18)

Để tiện trình bày tiếng Việt, số phần thích kết tính tốn khơng in theo kiểu chữ Courier

Chú thích Scheme

Chú thích (comment) dùng để diễn giải phần chương trình liên quan giúp người đọc dễ

hiểu, dễ theo dõi khơng có hiệu lực Scheme (Scheme bỏ qua phần thích thực hiện) Chú thích bắt đầu dấu chấm phẩy (;), viết dòng bất kỳ, từđầu dịng, cuối dịng Ví dụ :

; this is a comment line

(define x 2) ; định nghĩa biến x có giá trị

;;; The FACT procedure computes the factorial ;;; of a non-negative integer

(define fact (lambda (n)

(if (= n 0)

1 ; Base case: return (* n (fact (- n 1))))))

II. Các kiểu dữ liệu của Scheme

Kiểu liệu (data type) tập hợp giá trị có quan hệ loại với (related values) Các kiểu liệu xử lý tuỳ theo chất chúng thường có tính phân cấp Trong Scheme có hai loại kiểu liệu kiểu đơn giản (simple data type) kiểu phức hợp

(compound data type) Trong chương này, ta xét kiểu liệu đơn giản trước

II.1. Các kiểu dữ liệu đơn giản

Các kiểu liệu đơn giản Scheme bao gồm kiểu số (number), kiểu lơgích (boolean), kiểu ký tự(character) kiểu ký hiệu (symbol)

II.1.1. Kiu s

Kiểu số Scheme số nguyên (integer), số thực (real), số hữu tỷ (rational) số

phức (complex ) sau :

Kiểu số Ví dụ

số nguyên 52

số thực 3.0, -2.5

số hữu tỷ 6/10, 23/5

số phức 3+4i,

Scheme không phân biệt số nguyên hay số thực Các số không hạn chế vềđộ lớn, miễn nhớ cho phép

Với số, Scheme sử dụng phép tốn số học thơng dụng +, -, *, /, max, min, phép lấy bậc hai √⎯ so sánh số học với số lượng đối số tương ứng :

(+ x1 xn) > x1 + + xn

(- x1 x2) > x1- x2

(* x1 xn) > x1 * * xn

(19)

(quotient x1 x2) > phần nguyên (x1/ x2)

(remainder x1 x2) > phần dư phép chia nguyên (x1/ x2), lấy dấu x1

(modulo x1 x2) > phần dư phép chia nguyên (x1/ x2) , lấy dấu x2

(max x1 xn) > max (x1, , xn) (min x1 xn) > (x1, , xn) (sqrt x) > √⎯x

Các phép so sánh sau trả #t kết so sánh giá trịx1, , xn thoả mãn, ngược lại trả #f :

(= x1 xn) (< x1 xn) (<= x1 xn) (> x1 xn) (>= x1 xn) Ví dụ :

(* 9) > 362880

(= 5) > #f

(= 1 1 1) > #t

(< 5) > #t

(> 1) > #t

(<= 5) > #t

(>= 1) > #t

Thể tích hình cầu bán kính R : (* pi R R R)

Nhiệt độ Farenheit biểu diễn qua nhiệt độ Celsius C : (+ 32 (* 9/5 C))

Một biểu thức Scheme trộn lẫn lộn số nguyên số thực : (+ 2.3 5)

> 7.3

Phép tính số hữu tỷ : (* 2/3 5/2)

> 10/6

(20)

> -2

Ký tự

Một ký tự (character) Scheme có dạng #\<char> Ví dụ : #\a

> #\a ;chữ a thường #\A

> #\A ;chữA hoa #\(

> #\( dấu ngoặc trái

Chuỗi

Chuỗi (string) kiểu liệu phức hợp Scheme, gồm dãy ký tự tuỳ ý đặt hai dấu nháy kép, dấu nháy kép giữ nguyên giá trị chuỗi :

”Chào bạn !”

> ” Chào bạn !”

Tên

Mọi ngơn ngữ lập trình sử dụng tên để định đối tượng cần xử lý Trong Scheme, tên tạo thành từ chữ cái, chữ số dấu đặc biệt, trừ # () [] dấu cách (space) dùng để phân cách đối tượng

Tên Scheme bắt đầu chữ không phân biệt chữ hoa chữ thường Viết pi hay PI tên Nên chọn đặt tên «biết nói» (mnemonic) sử dụng dấu nối (-) Chẳng hạn tên sau hợp lệ :

pi * pi-chia-2

x + a34kTMNs

soup <=? is-this-a-very-long-name? lambda V19a list->vector

II.1.2. Kiu lơgích v t

Mọi ngơn ngữ lập trình sử dụng cấu trúc điều khiển sử dụng đến giá trị lơgích đó, cần biểu diễn giá trị lơgích Trong Scheme, có sẵn kiểu lơgích #t (true) #f(false)

Vị từ (predicate) hàm trả giá trị lơgích Theo quy ước, tên vị từđược kết thúc dấu chấm hỏi (?)

Thư viện Scheme có sẵn nhiều vị từ Sau số vị từ dùng để kiểm tra kiểu giá trị biểu thức :

(number? s) > #t s số thực, #f không (integer? s) > #t s nguyên, #f không (string? s) > #t s chuỗi, #f không (boolean? s) > #t s lơgích, #f không (procedure? s) > #t s hàm, #f khơng Ví dụ :

(string? 10)

Ngày đăng: 09/03/2021, 05:01

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan