+Logic[Dual] – Xây dựng đối ngẫu dual của biểu thức Boolean Cú pháp: Dualb; b – biểu thức Boolean Lệnh Dual trả về biểu thức đối ngẫu của b, tức là biểu thức được tạo ra bằng cách thay
Trang 1ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA: KHOA HỌC MÁY TÍNH
TIỂU LUẬN
LẬP TRÌNH SYMBOLIC
LẬP TRÌNH SYMBOLIC TRÊN MAPLE
Giảng viên hướng dẫn : PGS-TS ĐỖ VĂN NHƠN
Học viên thực hiện: NGÔ NGỌC THƠ _ CH1101139
Lớp : CH06
TP Hồ Chí Minh, tháng 1 năm 2013
Trang 2Lời mở đầu
Qua chuyên đề “Lập trình Symbolic”, tôi cũng như các bạn cùng lớp đều học được rất nhiều kiến thức bổ ích Tuy thời gian học dành cho môn này có giới hạn nhưng những tri thức trong chuyên đề này đã giúp tôi hình thành những cái nhìn rất mới về công nghệ cũng như ứng dụng của chúng vào trong công việc thực tiễn
Em xin chân thành cảm ơn PGS TS Đỗ Văn Nhơn giảng viên môn học lập trình Symbolic, đã truyền đạt những kiến thức quý báu Mỗi chuyên mục trong chuyên đề đều
có những ưu thế riêng và có thể áp dụng lý thuyết của môn học này vào thực tiển Tuy
nhiên do thời gian nghiên cứu có hạn nên tôi xin trình bày vấn đề “Lập trình symbolic trên Maple”
Đề tài thực hiện gồm các chương:
Chương I: Lập trình Maple cơ bản
Chương II: Lập trình Maple nâng cao
Chương III: Một số package và bài toán ứng dụng
Chương IV: Kết luận
Trang 3NHẬN XÉT
………
……….………
……….………
……….………
……….………
……….………
……….………
…….……….……
……….………
……….………
……….………
……….………
……….………
……….………
……….………
….……….………
……….………
……….………
……….………
……….………
……….………
……….………
………….………
……….………
……….………
………
Trang 4MỤC LỤC
CHƯƠNG 1: LẬP TRÌNH MAPLE CƠ BẢN 2
I BIẾN LẬP TRÌNH VÀ KÝ HIỆU TOÁN HỌC 2
II MỘT SỐ KIỂU DỮ LIỆU VÀ PHÉP TOÁN 3
III LỆNH GÁN 10
IV LỆNH ĐIỀU KIỆN 11
V VÒNG LẶP 12
VI LỆNH VÀ HÀM THOÁT 14
CHƯƠNG 2: LẬP TRÌNH MAPLE NÂNG CAO 15
I THỦ TỤC: 15
II LẬP TRÌNH VỚI MODULE 19
III TẠO PACKAGE – DÙNG MODULE ĐỂ TẠO GÓI THỰC 21
CHƯƠNG 3: MỘT SỐ PACKAGE VÀ BÀI TOÁN ỨNG DỤNG 24
I ĐẠI SỐ 24
II TỔ HỢP 26
III CÂY 28
IV BIỂU DIỄN MA TRẬN 30
V CÁC BÀI TOÁN VỀ ĐƯỜNG ĐI 33
CHƯƠNG 4: KẾT LUẬN 42
TÀI LIỆU THAM KHẢO 43
Trang 5CHƯƠNG 1: LẬP TRÌNH MAPLE CƠ BẢN
Tên (name): là một ký tự (letter) hay dãy ký tự bắt đầu ký tự theo sau có thể các
ký tự, ký số, dấu _ và có phân biệt ký tự hoa và thường Chiều dài tên tùy thuộc vào cấu hình máy tính: với máy 32-bit: 524.271 ký tự; 64-bit: 34.359.738.335 ký tự
Có 2 loại tên: Tên chỉ số (indexed name) và ký hiệu (symbol, non-indexed name)
+ Biểu thức bất kỳ có thể được gán một tên, gọi là biến Tên chưa được gán trị gọi là
ẩn Tên được tạo bởi toán tử “||” hoặc hàm cat
+ Biến bắt đầu bởi _Env là biến môi trường
+ Tên bắt đầu bởi dấu _ (trừ _Env) được dùng là tên biến toàn cục và được dùng trong
mã thư viện (library code) Tên rỗng “” không được gán trị
+ Tên chứa dấu / dùng cho mã thư viện
+ Tên kết thúc bởi dấu tilde ~ dùng trong giả thiết
+ Tên có thể được tạo ra bởi dãy ký tự rào bởi 2 dấu ``
Trang 6Mô tả: Hàm cat thường được dùng để nối các chuỗi và tên lại với nhau Các đối số được
nối là dạng hoặc chuỗi, tên hoặc đối tượng của kiểu `||` Kết quả của kiểu trả về bởi cat hoặc
`||`, tùy thuộc vào đối đầu tiên của cat
Chú ý: Nếu kết quả của cat là tên thì nó là tên toàn cục (global name), dù rằng có biến địa
phương cùng tên đang hoạt động
Dùng toán tử :: để phân cách biến và kiểu Ta có thể dùng để chỉ miền Ví dụ:
1 10
Để kiểm tra kiểu: type( e, t );
Trong đó: e là Biểu thức, t: là kiểu biểu thức đúng, như:
algebraic, algext, algfun, algnum, And,anyfunc, anything, Array, array, boolean, complex, complexcons, constant, equation, even, evenfunc, float, float[], fraction, function, infinity, integer, linear, list, listlist, logical, Matrix, matrix, monomial, name, negative, negint, negzero, NONNEGATIVE, nonnegative, nonnegint, nonposint, nonpositive, nonreal, nothing, numeric, odd, oddfunc, operator, Or, polynom, posint, positive, prime, procedure, radical, Range, range, rational,
realcons,real_infinity, relation, series, set, sqrt, stack, string, subset, symbol, table, tabular, taylor, TEXT, trig, truefalse, type, Vector, vector,…
1) Kiểu nguyên, hữu tỷ: integer, negzero, negative, negint, nonnegative, nonnegint,
nonposint, nonpositive, posint, positive, even, odd, prime, fraction (phân thức)
2) Kiểu thực, phức:anything, constant, float, nonreal, numeric, radical, sqrt,
true
true false - - false true
FAIL - FAIL
true - true
false FAIL - - false FAIL false true false FAIL true true true FAIL FAIL FAIL FAIL true FAIL FAIL
Trang 7evalb không thực hiện tính toán số học cho các bất đẳng thức <, <=, >, hay
>=, cần thực hiện các tính toán số học trước khi dùng evalb
5) Kiểm tra kiểu: type
Cú pháp:
type(expr, boolean);
type(expr, relation);
type(expr, logical);
với expr – là biểu thức bất kỳ
Hàm trả về true nếu expr đúng kiểu chỉ ra, ngược lại trả về false
Kiểu boolean nếu biểu thức là kiểu relation, logical hay chứa hằng true, false, FAIL
Kiểu relation nếu biểu thức loại: =, <>, <, <=
Kiểu logical nếu biểu thức loại: and, or, xor, implies, not
6) Các toán tử và lệnh trong gói Logic:
&and, &iff (<=>), &implies, &nand, &nor, ¬, &or, &xor, BooleanSimplify, Canonicalize, Contradiction, Dual, Environment, Equivalent, Export, Implies, Import, Normalize, Random, Satisfy, Tautology, TruthTable
Mô tả: Gói Logic là hệ logic dùng hai giá trị, trong khi đó logic Maple chuẩn dùng
ba giá trị Vì vậy, mọi biểu thức logic dùng trong gói Logic phải được biểu diễn qua các
số hạng của toán tử &and, &iff, &implies, &nand, &nor, ¬, &or, &xor
(Chú ý: a &nor b tương đương not(a or b))
Ta cần hoặc đưa vào trực tiếp các biểu thức trong hạng tử của các toán tử này theo Maple hoặc chuyển đổi biểu thức kiểu logical thành biểu thức với các toán hạng của các toán tử này bằng lệnh Logic[Import]
Chú ý rằng gói toán tử Logic không có thứ tự ưu tiên tương tự ứng với toán tử ba trị Đặc biệt, mọi toán tử có thứ tự ưu tiên là a &or b &and c tương đương (a &or b)
&and c, không phải a &or (b &and c)
+ Logic[BooleanSimplify] – đơn giản biểu thức Boolean Cú
pháp: BooleanSimplify(b); b – biểu thức Boolean
+ Logic[Canonicalize] – đưa về biểu diễn chính tắc (canonical) của biểu thức
Cú pháp: Canonicalize(b, alpha, form);
Tham số:
b - Boolean expression
alpha - (option) tập hoặc danh sách các tên
form - (option) biểu thức dạng form=fname
Trang 8Lệnh Canonicalize chuyển đổi biểu thức boolean thành dạng thức chính tắc
Dùng dạng chính tắc được xác định bởi tùy chọn form=fname Mặc nhiên là DNF Dạng thức chính tắc được cho theo tên alpha Chú ý, alpha là cần thiết khi chọn
CNF hay DNF
Các dạng thức chính tắc:
MOD2 – Biểu thức logic được chuyển đổi tương đương dạng thức chính tắc modulo 2 CNF - conjunctive normal form
DNF - disjunctive normal form
+ Logic[Tautology] – Kiểm tra hằng đúng (tautology)
Logic[Contradiction] – Kiểm tra sự mâu thuẫn (contradiction) Cú
Nếu có tham số p và kiểm tra trả về false, thì các giá trị được gán cho p là chứng minh kết qủa phủ định Ngược lại, p được gán giá trị NULL Chú ý rằng kiểm tra có thể nhanh hơn nếu thiếu p
+Logic[Dual] – Xây dựng đối ngẫu (dual) của biểu thức Boolean
Cú pháp: Dual(b); b – biểu thức Boolean
Lệnh Dual trả về biểu thức đối ngẫu của b, tức là biểu thức được tạo ra bằng cách thay thế
&and bởi &or, &or bởi &and, còn lại ¬ không đổi, và mở rộng cho các toán tử còn lại của công thức chứa các số hạng có &and, &or, ¬
+ Logic[Export] – Biểu diễn theo các số hạng của toán tử gói Logic
Cú pháp: Export(expr, form);
expr – Biểu thức phù hợp dùng bởi gói Logic
form – biểu thức dạng form=MOD2 hay form=boolean
Export biến đổi biểu thức expr thành một trong kiểu đã chỉ ra
MOD2: biểu thức Boolean chuyển đổi thành dạng tương đương modulo 2 bằng ánh xạ
&and thành tích, &xor thành cộng, true thành 1, và false thành 0
boolean: toán tử bất kỳ trong gói Logic biểu diễn bằng biểu thức được thay thế với các toán tử logíc bộ ba (ternary) tương đương, ví dụ : and, or, và not
+Logic[Import] – Biểu diễn theo các số hạng của toán tử trong gói Logic
Cú pháp : Import(expr, form);
expr – biểu thức
form – biểu thức dạng form=MOD2 hay form=boolean
Import biến đổi biểu thức Maple theo dạng phù hợp chỉ ra
MOD2: Đa thức đưa vào được chuyển đổi thành biểu thức boolean bằng cách ánh xạ tích thành &and, cộng thành &xor, 0 thành true, và 1 thành false
Trang 9boolean: Bất kỳ toán tử logíc bộ ba (ví dụ and, or, và not) thì biểu thức biểu diễn được thay thế với các toán tử Logic tương đương
+Logic[Normalize] – Chuẩn hoá biểu thức Boolean
Cú pháp: Normalize(b, form);
b - biểu thức Boolean
form - (option) biểu thức dạng form=DNF hay form=CNF
Lệnh Normalize chuyển đổi biểu thức Boolean đã cho sang dạng chỉ ra bởi form
Dạng form thường dùng để xác định bởi lựa chọn form Giá trị của form có thể là DNF (disjunctive normal form) hay CNF(conjunctive normal form) Nếu không có lựa chọn được cho như vậy thì dạng chuẩn được dùng
Việc chuyển đổi được thực hiện bằng cách áp dụng luật phân bố hay De Morgan cho biểu thức Biểu thức kết quả là không bảo đảm là duy nhất, tối thiểu hoặc dạng chính tắc
+ Logic[Random] – Xây dựng hàm ngẫu nhiên Boolean
Cú pháp: Random(alpha, opt);
alpha – danh sách hoặc tập các ký hiệu được biểu diễn theo alphabet
opt - (option) phương trình dạng form form=fname, với fname là một trong các từ khóa CNF, DNF, hay MOD2
Random trả về biểu thức Boolean trong dạng chính tắc (canonical) đã chỉ Mặc nhiên, dạng tuyển chuẩn (disjunctive normal form) được dùng Biểu thức Boolean trả về
là dạng chuẩn theo ký hiệu (symbol) trong alpha
+ Logic[Satisfy] – Tìm một giá trị thỏa mãn biểu thức
Cú pháp : Satisfy(expr, alpha)
Tham số :
expr - Biểu thức logic
alpha - (option) danh sách hoặc tập các tên
Mô tả :
Satisfy trả về tập các phương trình biểu diễn gán trị cho các biến trong biểu thức expr mà thỏa mãn biểu thức Nếu expr không thỏa mãn thì trả về NULL
Có tùy chọn thứ 2, thì định giá mọi tên biến trong alpha
+ Logic[TruthTable] – Xây dựng bảng chân trị của biểu thức Boolean Cú
pháp : TruthTable(expr, L, opt)
Tham số:
expr – biểu thức Boolean
L - danh sách các danh hiệu chuẩn (identifier) xuất hiệu trong biểu thức
opt - (option) phương trình dạng form=tblform, ở đây tblform hoặc là boolean hoặc MOD2
Mô tả:
TruthTable trả về bảng chân trị tương ứng với biểu thức Boolean expr
Tham số L, là danh sách các danh hiệu chuẩn trong biểu thức, xác định thứ tự dùng cho các chỉ số bảng Tức là, nếu T là bảng trả về và L=[x1, ,xn], với x1, ,xn, là các danh hiệu trong biểu thức, thì T[v1, ,vn] tương đương eval(expr, [x1=v1, , xn=vn]) Lựa chọn form=tblform chỉ kiểu nhập xuất; mặc nhiên là boolean Nếu form=MOD2 được cho, thì chỉ số và dữ liệu vào là các số 0 và 1
Kiểu chuỗi: with(StringTools):
Cú pháp : StringTools[command](arguments); command(arguments);
Trang 101/ Tìm chuỗi:
biêt hoa thường: SearchText(pattern, string, range);
Không phân biệt hoa thường: searchtext(pattern, string, range);
2/Kiểm tra char là ký trắng hay không: IsSpace(char);
5/ Xóa chuỗi: Delete( s, rng );
6/ Chèn chuỗi: Insert( s, position, t );
7/ Trích chuỗi con: SubString( s, r );
8/ Tách chuỗi:
chuỗi theo ký tự mẫu :Split( s, sep );
chuỗi theo ký tự hoa: CaseSplit( s );
chuỗi theo chiều dài bằng nhau: LengthSplit( s, len );
LengthSplit( s, len, pad = ch );
9/ Chuyển chuỗi thành dãy ký tự và ngược lại:
11/ Xóa ký tự kết thúc hàng, cuối chuỗi:
Chomp( s ); Xóa ký tự kết thúc chuỗi
12/ Xóa ký tự trắng trong chuỗi: Squeeze(s); DeleteSpace(s);
14/ Thêm ký tự rào(fence) vào chuỗi văn bản : Fence( s, leftfence, rightfence)
Trang 1115/ Điều chỉnh văn bản thụt vào (indent) với số lượng chỉ ra (defalt=8)
nt( s );
t( s, lineindent );
16/ Tìm ký tự rào: MatchFence( s, pos );
Thủ tục MatchFence chỉ định vị trí (đầu tiên) gặp ký tự rào trong văn bản s của ký tự rào kia ( trong cặp ký tự rào ) ở vị trí pos Nếu không có trả về 0 Nếu s[pos] không
phải ký tự rào, tức là, không phải một trong các ký tự : {"(",")","[","]","{","}"}, thông báo lỗi
17/ Cắt ký tự trắng trước và sau chuỗi:TrimLeft( s ); TrimRight( s ); Trim( s )
18/ Tính tần số xuất hiện của mỗi ký tự trong string:
CharacterFrequencies( s, filter );
s - string
filter - (option) tên hoặc chuỗi ; lớp ký tự lọc cần tính
CharacterFrequencies(s) trả về biểu thức dạng character = frequency, với character là ký tự, và frequency số lần có mặt của ký tự tương ứng trong s
CharacterFrequencies( s ) tương đương
seq( ch = CountCharacterOccurrences( s, ch ), ch = Support( s ) ), nhưng nó tính
toán hiệu quả hơn
20/ Chiều dài của đối tượng: length(expr);
expr là số nguyên, thì số ký số trả về (chiều dài số 0 là 0 và chiều dài số âm bằng chiều dài giá trị tuyệt đối của nó)
expr là chuỗi, thì số ký tự trong expr được trả về
expr đối tượng rtable, thì số từ lưu trữ chiếm giữ bởi rtable được trả về (gồm dữ liệu, thuộc tính, và cấu trúc dữ liệu của nó)
23/ Kiểm tra chuỗi chứa ký tự đã cho: Has( s, ch );
24/ Kiểm tra chuỗi có ký tự thường, hoa, hay có ký tự chữ không
HasUpper(s);
HasAlpha(s);
24/ Xác định chuỗi có ký tự chữ hoặc số : HasAlphaNumeric(s);
25/ Xác định chuỗi chứa ký tự ASCII : HasASCII(s);
26/ Xác định chuỗi có kí số nhị phân, thập lục phân, bát phân
HasBinaryDigit(s);
HasHexDigit(s);
it(s);
Trang 1227/ Xác định chuỗi có chứa ký tự điều khiển: HasControlCharacter(s);
28/ Xác định chuỗi có chứa ký tự thập phân: HasDigit(s);
29/ So sánh thứ tự từ điển (lexicographical order) của các chuỗi
CompareCI(s1, s2) so sánh không phân biệt hoa thường(case-insensitive) s1 và s2
30/ Sinh chuỗi Fibonacci : Fibonacci( n, a, b );
n – Số nguyên không âm, mà số hạng chuỗi Fibonacci thứ n a –
ký tự;
b – ký tư;
Qui tắc : cho 2 ký hiệu a và b, chuỗi Fibonacci thứ n :
Fibonacci( n, a, b ) = cat( Fibonacci( n - 1, a, b ), Fibonacci( n - 2, a, b ) ), với n >
1, và Fibonacci( 0, a, b ) = b, Fibonacci( 1, a, b ) = a, chiều dài Fibonacci( n ) bằng n+1 số Fibonacci
Chú ý: combinat[fibonacci] – tính dãy số hay đa thức Fibonacci
fibonacci(n); fibonacci(n, x);
với n, x – biểu thức đại số
31/ Kiểm tra hai chuỗi có liên hợp không: IsConjugate( s, t );
Hai chuỗi liên hợp một trong chúng là hoán vị vòng quanh của chuỗi kia
Nếu s, t là rỗng, lệnh trả về true
32/Kiểm tra chuỗi có palindrome : IsPalindrome( s );
Chuỗi gọi là palindrome nếu ta đảo ngược chuỗi, chuỗi không thay đổi
33/Kiểm tra một số có phải là chu kỳ của một từ : IsPeriod( w, p );
IsPeriod(w,p) kiểm tra số nguyên dương p là chu kỳ của chuỗi w p được gọi là chu kỳ của chuỗi s nếu mọi số nguyên i với 1 <= i <= length( s ) - p, có s[ i ] = s[ i + p ] Nếu p
là chu kỳ w, trả về true ngược lại trả về false
34/ Kiểm tra chuỗi có hoán vị : IsPermutation( s );
Một chuỗi gọi hoán vị (permutable) nếu và chỉ nếu mỗi ký tự trong chuỗi chỉ xuất hiện một lần
35/ Kiểm tra chỗi có nguyên thủy (primitive): IsPrimitive( s );
Một string là primitive nếu nó không thể được viết như là một tính chất lũy thừa
(proper power) của chuỗi khác Nói cách khác, s là primitive nếu Repeat( t, n ) = s thì
suy ra hoặc s = "" hoặc s = t và n = 1
36/ Điền đầy một chuỗi : Fill( ch, n );
37/Lặp lại một chuỗi : Repeat( s, n )
38/ Sinh chuỗi trên miền nguyên Tabulate( p, n )
39/ Sinh chuỗi từ các ký tự trong chuỗi theo chiều dài Generate(len,supp );
40/ Tạo nhóm các từ bằng cách dùng tchat( true/false) : Group(tchat,Chuoi);
41/Trả về chuỗi ngẫu nhiên:Random(len,alphabet); Randomize(); Randomize(seed);
e Cấu trúc dữ liệu bảng và mảng :
Trang 13+ Bảng:
Lệnh tạo bảng: table(F,L);
F : Hàm chỉ mục (tùy chọn)
L : danh sách hay tập hợp các giá trị khởi tạo cho bảng (tùy chọn)
Hàm table() tạo bảng trong Maple Nếu đối số truyền cho hàm là một danh sách các đẳng thức thể hiện mối quan hệ giữa các chỉ mục và các giá trị của bảng thì danh sách đó được dùng để định rõ phần khởi tạo cho các phần tử của bảng Nếu hàm table không nhận được đối số nào, thì khởi tạo một bảng rỗng
Bất kỳ tên biến trong chương trình nào của Maple cũng có thể nhận giá trị là một bảng Sau khi gán, tên biến trở thành tên bảng Nội dung của toàn bộ bảng thì được in ra màn hình bằng cách dùng lệnh print
Bảng là cấu trúc dữ liệu được Maple dùng để lưu trữ theo từng cặp chỉ mục (khóa) và giá trị
Hàm chỉ số F có thể là thủ tục hay một tên, có thể là: symmetric, antisymmetric, sparse, diagonal, và identity
Hàm :
indices(t); dãy các khóa của bảng
entries(t); dãy giá trị của bảng
Tham số :
t - là table hay array
Hàm indices và entries trả về dãy chỉ mục (hay khóa) và giá trị tương ứng với table hay array, t là tên hay bộ dữ liệu lưu trữ
Trật tự của các chỉ mục và các phần tử do hàm indices và hàm entries cho biết không nhất thiết trùng với trật tự khi chúng được nhập vào Tuy vậy, dãy các chỉ mục do hàm indices và dãy giá trị do hàm entries cho vẫn có sự tương ứng một-một
+ Mảng: Mảng là một kiểu của cấu trúc dữ liệu bảng, trong đó các chỉ mục của một
mảng bất kỳ đều là các số nguyên và phạm vi của các chỉ số mảng được định rõ khi khai báo mảng thông qua hàm array
Để tạo một mảng, ta phải định rõ phạm vi chỉ số cho mỗi chiều của mảng Thêm vào đó,
ta có thể có mảng thưa, đối xứng, phản đối xứng hay theo một kiểu số định nghĩa riêng của ta
Việc thay đổi và sao chép mảng làm việc giống như trong mảng Nói chung việc sử dụng bảng và mảng giống nhau, trừ việc giới hạn chỉ mục
Cú pháp: array( indexfcn, bounds, list);
Tham số:
indexfcn - (option) hàm chỉ số
bounds - (option) dãy các miền
list - (option) danh sách các giá trị khởi tạo
indexfcn có thể là thủ tục hay tên chỉ định chỉ số để thực hiện
III LỆNH GÁN
lhs := rhs;
Toán tử := gán lhs cho giá trị của rhs Vế trái của toán tử gán phải được tính toán
Trang 14thành tên, một hàm gọi, một dãy biểu thức của tên hoặc các hàm gọi
Đầu tiên, vế trái được tính toán thành một tên Tiếp theo, vế phải được tính toán biểu thức Cuối cùng, lệnh gán mới thực hiện Giá trị của lệnh gán là vế phải
Nếu vế trái là dãy tên, vế phải cũng phải là dãy biểu thức với tương ứng số phần tử bên trái Lệnh gán thức hiện cho từng cặp tên và biểu thức
Khi dùng bảng(table) hay ma trận, ta phải cho kích thước rõ ràng (bằng số) Tuy nhiên, nhiều lúc không thể xác định trước kích thước mà chỉ khai báo thông qua biến Việc này Maple và các ngôn ngữ khác không chấp nhận
Ví dụ: > M:=matrix(n,n,(i,j)->i+j-1);
Error, (in matrix) 1st and 2nd arguments (dimensions) must be non negative integers Lý
do vì các chương trình biên dịch (compiler) bắt buộc phải biết trước kích thước (một giá trị bằng số) để cấp phát một lượng bộ nhớ, mà số lượng bộ nhớ này rất hạn chế và được các hệ điều hành cấp phát cho compiler ngay từ lúc đầu khi chạy các compiler này Ta tạm gọi là vùng bộ nhớ tự động (automatic memory) Để giải quyết vấn đề này, các ngôn ngữ lập trình cho phép người khai báo các kích thước hình thức (bằng biến số) nhưng ở một vùng nhớ nằm ngoài bộ nhớ tự động, gọi là vùng nhớ heap (heap memory) và việc này gọi là cấp phát bộ nhớ động (dynamic allocate) Nói chung, cấp phát bộ nhớ động trong các phép tính dùng mãng, ma trận là tương đối phức tạp Nó đòi hỏi lập trình viên phải chủ động trong công việc này, cụ thể là xin cấp phát khi cần và xóa vùng đã xin không dùng đến nữa, bằng không sẽ bị tràn bộ nhớ (overflow) dễ làm treo máy
Để xử lý khó khăn này Maple có một công cụ tuyệt vời để tránh các rắc rối nói trên Tất cả đều được giải quyết bằng hàm hoặc toán tử mũi tên một cách thông minh Ta thử với dạng sau:
> M:=’matrix(n,n,(i,j)->i+j-1)’;
M:=matrix(n,n,(i,j)->i+j-1);
Dấu „ dùng để dời công việc tính toán cho đến lúc nhập giá trị cụ thể Tránh thông báo sai như trên Sau đó, lần lượt cho n = 3, n = 4:
> n:=3:M3:=eval(M):n:=4 :M4:=eval(M): „M[3]‟=eval(M):,‟ M[4]‟=eval(M);
Tuy nhiên, việc nhập giá trị n mỗi khi dùng chưa phải là giải pháp hoàn hảo Cách hay nhất biến đổi sao cho công việc khai báo ma trận M trở nên hoàn toàn tự động mà không cần phải khai báo lại n Muốn thế ta phải cho n thành một biến số của hàm mũi tên, nghĩa là:
M:=n->matrix(n,n,(i,j)->i+j-1);
Và để khai báo M với kích thước bất kỳ, ta cần nhập giá trị của kích thước:
‟M[3]‟=M(3); ‟M[4]‟=M(4); ta lại được kết qủa trên
Cú pháp :
if <conditional expression> then <statement sequence>
| elif <conditional expression> then <statement sequence> |
| else <statement sequence> |
end if
(Chú ý: các đoạn nằm giữa | | là lựa chọn.)
Toán tử if : `if`(conditional expression, true expression, false expression) Mô
tả :
Trang 15Câu lệnh chọn <statement sequence> để rẽ nhánh tùy thuộc vào <conditional expression>
Cấu trúc elif conditional expression then statement sequence có thể lặp lại số lần bất
kỳ Từ khóa elif thay cho else if Dùng elif tránh phải dùng end if
<conditional expression> là biểu thức Boolean dùng các toán tử liên hệ (<, <=, >, >=,
=, <>), toán tử logic (and, or, not), và các tên (true, false, FAIL)
<conditional expression> được tính toán trả về true hoặc false hoặc FAIL; ngược lại, một lỗi sai xảy ra
Câu lệnh sau else được thi hành nếu <conditional expressions> là false hoặc FAIL Toán tử if cần 3 đối số và trả về giá trị thứ hai hoặc ba dựa vào sự đúng hoặc sai của đối thứ nhất Tức là đối thứ nhất tính toán trả về true, thì đối thứ hai được tính toán và trả về Nếu đối thứ nhất được tính toán là false hoặc FAIL, thì đối thứ ba được tính toán và trả
về
Khi dùng toán tử if, tên hàm phải rào giữa 2 dấu ` (left single quote), nó là từ dành riêng của Maple
Câu lệnh lồng nhau: Các câu lệnh trong Maple được phân cấp, được xác định bởi
sự lồng nhau của các câu lệnh chọn, các lệnh lặp và các thủ tục Nói cụ thể, cấp đỉnh (tương tác- interactive) là cấp 0; câu lệnh trong thân của lệnh chọn hoặc lặp là cấp 1, hoặc cấp 2 nếu lồng nhau hai lần, …
Thiết lập printlevel là vì việc hiển thị kết qủa của mọi câu lệnh thi hành là chỉ định cấp bởi printlevel Mặc nhiên, printlevel đầu tiên được thiết đặt là 1 Khi một kết qủa, câu lệnh được đặt bên trong các vòng lặp lồng nhau hoặc các câu lệnh chọn lồng nhau, nó cần thiết phải thiết lập printlevel giá trị cao hơn để thấy kết quả mọi câu lệnh đặt trong vòng lặp hoặc lệnh điều kiện
Một phương pháp cho hiển thị kết quả của câu lệnh là lồng bên trong các vòng lặp hoặc lệnh điều kiện là dùng liên kết với lệnh print
for…while…do - Thoát khỏi và trở lại đầu vòng lặp
+ Vòng lặp for…while…do; Cú
pháp :
| for <name> | | from <expr> | | by <expr> | | to <expr> | | while <expr> |
do <statement sequence> end do;
Hoặc:
| for <name> | | in <expr> | | while <expr> |
do <statement sequence> end do; (Chú
ý: các đoạn nằm giữa | | là lựa chọn.) Mô tả:
Sự lặp lại câu lệnh <statement sequence> với số lần biết trước (dùng for to) hoặc cho tới khi điều kiện nào đó thỏa (dùng while) Cả hai dạng có thể xuất hiện đồng thời
Nếu bỏ qua from hoặc by, thì mặc nhiên from 1 hoặc by 1 được dùng
expr trong while là biểu thức Boolean, nó được tính toán trả về true hoặc false; ngược lại trả về thông báo sai
Kiểm tra to expr và while expr được kiểm tra đầu tiên của mỗi vòng lặp Chú ý trong trường hợp to expr, expr chỉ được tính toán một lần tại thời điểm bắt đầu vòng lặp, và giá trị này dùng để kết thúc việc kiểm tra; trong trường hợp while expr, expr được tính toán lại
Trang 16với mỗi vòng lặp
Trong vòng lặp chứa for to và while, thì điều kiện to expr được kiểm tra đầu tiên Nếu điều kiện không thỏa, vòng lặp kết thúc không có kiểm tra điều kiện while expr Nếu không có to expr hoặc không có while expr, thì vòng lặp không xác định
(infinite) Để thoát ra vòng lặp ta dùng break, và return cho thủ tục, hoặc lệnh quit Dùng in expr trong trường hợp các biến chỉ số cần lấy giá trị của toán hạng hoặc trong các giá trị lấy từ biểu thức chỉ ra expr để xác định dùng op
Với dãy biểu thức, biến chỉ số lấy giá trị từ toán hạng được xác định bởi op([ expr ])
Với bảng (table), biến chỉ số lấy giá trị từ toán hạng xác định bởi map(op,[entries(T)]) Với rtable, biến chỉ số có thể không cần lấy các toán hạng theo thứ tự chỉ số
Chú ý: Trong in expr của vòng lặp, expr được tính toán chỉ một lần tại thời điểm bắt
đầu vòng lặp
Các câu lệnh trong Maple được ghi nhận cấp (level), xác định bởi các điều kiện lồng nhau hoặc các câu lệnh lặp lại hoặc các thủ tục lồng nhau Cụ thể, tại đỉnh (top) cấp 0; các câu lệnh trong phạm vi lệnh chọn hay lặp có cấp 1, hoặc cấp 2 nếu lồng nhau hai lần, …
+ Các dạng của vòng lặp :
▫ for <name> from <expr> by <expr> to <expr> while <expr>
do <statement sequence> end do;
▫ for <name> in <expr> while <expr>
do <statement sequence> end do;
▫ while <expr>
do <statement sequence> end do;
▫ for <name> from <expr> by <expr> to <expr>
do <statement sequence> end do;
▫ for <name> in <expr>
do <statement sequence> end do;
+ Thoát khỏi và trở lại đầu vòng lặp
▫ Lệnh break : thoát khỏi vòng lặp
Mô tả:
Khi lệnh break được thi hành, thì kết qủa là thoát từ bên trong nhất của vòng lặp (for/while/do) trong phạm vi xảy ra
Sau khi thoát, thi hành tiếp câu lệnh đầu tiên sau lệnh lặp
Gặp lỗi sai nếu break được thi hành trong ngữ cảnh khác với phạm vi lệnh lặp
Trong Maple V Release 5.1 và trước đó, break là symbol của Maple, trong Maple 6 và về sau, break là từ khoá của Maple
▫ Lệnh next: trở về đầu vòng lặp
Mô tả:
Khi lệnh next được thi hành, kết quả là thoát khỏi từ câu lệnh hiện hành statement sequence (tức là, khối do-end do) tương ứng với lệnh lặp bên trong nhất (for/while/do) trong phạm vi nó thi hành
Thoát từ dãy lệnh hiện hành (statement sequence) nghĩa là cho phép thi hành tiến trình với bước lặp tiếp của lệnh lặp
Chú ý: "tiến trình với bước lặp tiếp'' nghĩa là tăng chỉ số của bước lặp rồi kiểm tra việc kết thúc trước tiến trình Vì vậy, việc thoát từ vòng lặp có thể xảy ra
Gặp lỗi sai, nếu next thi hành trong ngữ cảnh khác với phạm vi vòng lặp
Với Maple V Release 5.1 và sớm hơn, next là symbol của Maple Với Maple 6 và sau
Trang 17này, next là từ khoá trong Maple
kế cần kiểm tra hoặc trả về tường thuật trạng thái của ứng dụng (như là
ERRORLEVEL trong hàng lệnh tiện ích Window và $ trong tiện ích UNIX), Maple trả
về trạng thái của 0
Hàm `quit`(`done` và `stop` là tương đương) kết thúc hàng lệnh trong bộ phận Maple
và trả về người sử dụng tiện ích từ Maple khi bắt đầu expr chuyển cho `quit` phải được tính toán thành số nguyên, và nó chuyển trạng thái là quay lại tiện ích Miền của giá trị là 0 255, nếu expr không nguyên hoặc ngoài vùng giá trị thì có thông báo lỗi và Maple sẽ không kết thúc
Chú ý: quit, done,và stop là các từ khoá trong ngôn ngữ Maple, vì thế chúng phải được đóng trong 2 dấu ( ` ) khi dùng với dạng hàm
Trang 18CHƯƠNG 2: LẬP TRÌNH MAPLE NÂNG CAO
argseq - Tên tham số hình thức
type - (option) xác nhận kiểu giá trị trả về
nseq - (option) Tên biến địa phương / toàn cục và các lựa chọn
useq - (option) Tên của gói mà thủ tục sử dụng
var1,var2 - (option) tên của biến địa phương
type1,type2 - (option) Xác định kiểu của biến địa phương
stringseq - Hàng mô tả của thủ tục
statseq - Thân của thủ tục
Mô tả:
Một thủ tục (procedure) là một biểu thức đúng được gán cho một tên
argseq được đặt trong ngoặc đơn có thể là NULL, chỉ tên tham số hình thức Mỗi tham số là một ký hiệu theo sau là lựa chọn type, đi trước type có 2 dấu hai chấm (::) Nếu có type, Maple sẽ đưa ra lỗi sai nếu tham số thực không cùng kiểu (type) được chuyển cho tham số hình thức của hàm Maple cũng đưa ra lỗi sai nếu đối số bị bỏ qua Số tham số thực phải bằng số tham số hình thức Nếu nhiều hơn thì tham số thực thừa bị bỏ qua
argseq được đặt trong dấu ngoặc đơn theo sau :: và kiểu (type) và dấu ; , đây không
phải là khai báo về kiểu, mà là một xác nhận (assertion) về kiểu Nếu
kernelopts(assertlevel) được thiết đặt bằng 2, thì kiểu của giá trị trả về được kiểm tra như
là sự trả về của thủ tục
Cụm từ local nseq; , global nseq; , uses useq; , và options nseq; là các lựa chọn Nếu
có, tương ứng là tên biến địa phương, toàn cục, tên của gói được dùng và các lựa chọn đang có hiệu lực uses là ký hiệu của lệnh use Lệnh proc() uses LinearAlgebra; end proc tương đương proc() use LinearAlgebra in end use; end proc
Biến địa phương xuất hiện trong local nseq; cụm từ có thể có lựa chọn theo sau :: và kiểu (type) Trong trường hợp có kiểu trả về, đây không phải công bố về kiểu mà là một kiểu xác nhận Nếu kernelopts(assertlevel) được thiết đặt bằng 2, bất kỳ một việc gán trị cho biến với kiểu xác nhận được kiểm tra trước khi lệnh gán được tiến hành Có description stringseq; chỉ ra một hay nhiều hàng mô tả về thủ tục Khi thủ tục được in, những thông tin mô tả này cũng được in theo Ngay trong thủ tục thư viện, thân thủ tục bị bỏ qua khi đang in nhưng dòng mô tả lại được in
Hàm op có thể truy xuất 8 toán hạng của thủ tục:
op 1 là argseq các tham số hình thức;
op 2 là nseq biến địa phương;
Trang 19op 8 là kiểu trả về (return type, nếu có)
Chú ý : Để truy xuất dùng op(số,eval(f)), số=1,2,…,8
Có thể các toán hạng này là null
Chú ý: Với option remember hay options remember
Dùng time(); hay time(x); kiểm tra thời gian tính toán
Kết hợp với mỗi thủ tục Maple là ``remember table'' Bảng ghi nhớ (remember table)
được phụ trợ như là op 4 của cấu trúc thủ tục dùng op(4,eval(f)) nếu tên f có thủ tục đã
xác định đã gán tên cho nó Nó có thể được vận dụng như một bảng thông thường Nếu lựa chọn remember được chỉ ra trong vùng của thủ tục Maple, thì cuối của mỗi công việc của thủ tục, dữ liệu được xây dựng trong bảng ghi nhớ của nó mà kết quả mỗi bản ghi là
do đối số chỉ ra Dữ liệu sau của thủ tục được nhận từ dữ liệu trước đó của bảng ghi nhớ
Bảng ghi nhớ của thủ tục có thể được cập nhật rõ ràng bởi hàm gán dạng f(x) := y Bảng ghi nhớ của thủ tục có thể bị xoá bởi forget(f)
remember dùng viết mã một hàm đệ qui theo các số tự nhiên không mất thời gian tính
toán lại Ví dụ, dãy số Fibonacci :
f := proc(n) if n<2 then n else f(n-1)+f(n-2) end if end proc;
f(1000);
time();
nếu cần hiệu quả thời gian:
f := proc(n) option remember;
if n<2 then n else f(n-1)+f(n-2) end if end proc;
f(1000);
time();
Chú ý : - system( "date" ); thay đổi ngày hệ thống
- Khi thủ tục được in với hàm print, và interface(verboseproc=3) thì nội dung
của bảng ghi nhớ cũng được in theo sau thủ tục
- Bảng ghi nhớ được xây dựng bên trong thủ tục evalf
+ Biến địa phương, toàn cục:
Nếu biến chưa công bố thì để xác định là địa phương hay toàn cục thì theo luật sau: Biến được tìm thấy trong số biến địa phương (local) và toàn cục (global) (hiện hay ẩn) trong phạm vi bắt đầu phía trong nhất các thủ tục Nếu tên được gặp như một tham số hoặc biến địa phương hay toàn cục, tức là biến bị ràng buộc (dựa vào khai báo local hay global) Ngược lại, các biến tạo ra bởi lệnh gán, hay biến điều khiển của vòng lặp là biến địa phương Mọi biến khác là toàn cục Chú ý tên bắt đầu với _Env là biến môi trường
Thủ tục chẳng qua là tính toán đặc biệt (như table) vì vậy nếu tên f đã được gán cho thủ tục thì:
o f tính toán thành tên f;
o eval(f) sinh ra cấu trúc thật sự của thủ tục;
o op(eval(f)) sinh ra dãy 8 toán hạng theo trên
Trang 20Thủ tục được gán cho tên f thì gọi thủ tục ta dùng f(arguments) Giá trị của thủ tục là giá trị của câu lệnh cuối cùng được thi hành hoặc là giá trị của biểu thức trong return
+ Truyền tham biến : khi dùng thủ tục : name(exprseq);
Đầu tiên, name được tính toán, và giả sử thủ tục được định nghĩa với các tham số hình thức: param1, , paramn
Kế đó, các tham số thực expr1, , exprn (trong exprseq) được tính toán (các đối được tính toán theo tuần tự từ trái sang phải)
Mỗi tham số hình thức được kiểm tra kiểu cho tham số thực Nếu không giống nhau về kiểu sẽ gây lỗi Để chỉ tham số hình thức p kiểu t, ta viết p::t trong danh sách tham số Chú ý thêm kiểu cho tham số là không bắt buộc
Tiếp đó mỗi tham số hình thức parami trong thủ tục được nhận trị từ tham số thực tương ứng expri Chú ý, các tham số này sẽ không được tính toán lại trong quá trình thủ tục thi hành
Số tham số thực không nhất thiết phải giống như tham số hình thức chỉ ra
+ Tham số:
args – Dãy các tham số thực chuyển cho thủ tục
nargs – Số tham số chuyển cho thủ tục
Cú pháp:
args hay args[i] hay args[i j]
nargs Trong phạm vi thủ tục, tên đặc biệt args có giá trị dãy biểu thức tham số thực trong thủ tục được gọi
Dùng toán tử lựa chọn dãy biểu thức này, args[i] là tham số thực thứ i, và args[i j] dãy tham số thực từ thứ i đến thứ j
Và trong thủ tục, nargs là số phần tử của dãy biểu thức args
+ Lệnh return – Trả lại kết qủa từ thủ tục (procedure)
RETURN - Trả lại kết qủa từ thủ tục (cũ ) Cú
pháp:
return expr1, expr2,
RETURN(expr1, expr2, ) Tham số:
expr1, – dãy biểu thức (có thể rỗng)
Mô tả:
Một dạng thông thường của sự trả về từ thủ tục gọi xảy ra khi thi hành ``xuyên suốt'' câu lệnh cuối của dãy lệnh tạo thân thủ tục, trong trường hợp này giá trị của thủ tục gọi là giá trị của câu lệnh cuối đã thi hành
Lệnh return sự trả về lập tức tại thời điểm nơi thủ tục hiện hành được gọi
Nếu sự trả về của lệnh return thì giá trị của thủ tục gọi là dãy biểu thức chỉ ra sau return
Lệnh return chỉ xuất hiện bên trong một thủ tục hay module
Lệnh return xuất hiện bên trong thân module là dừng thi hành module trong khoảng thời gian mà nó tính toán Dãy biểu thức theo sau return có thể là rỗng (NULL)
Tên FAIL thường dùng trong thủ tục thư viện Maple là giá trị trả về chỉ định việc tính toán bị thất bại
Lệnh RETURN là lệnh cũ, dùng cho những bản Maple cũ Vì vậy, không nên dùng
Trang 21RETURN
+ Thủ tục lồng nhau:
+ Ghi và lấy lại thủ tục: Khi thiết kế xong thủ tục ta có thể lưu trữ thủ tục trên đĩa:
save tentt,”tênvadiachi”; và lấy thủ thủ để dùng : read ”tênvadiachi”;
+ Bẫy lỗi:
error - trả về thông báo khi gặp lỗi sai từ thủ tục
ERROR - trả về về thông báo khi gặp lỗi sai từ thủ tục (phiên bản cũ)
Cú pháp:
error msgString, msgParam1, msgParam2,
ERROR(expr1, expr2, )
Tham số:
msgString - văn bản thông báo sai
msgParami - Các tham số thay thế vào msgString
expr1, - Dãy biểu thức (có thể rỗng)
Câu lệnh error đưa vào một ngoại lệ Việc thi hành dãy câu lệnh hiện hành bị
ngắt, và ngăn xếp khối và thủ tục gọi được lấy ra cho tới khi hoặc gặp được ngoại lệ điều khiển hoặc việc thi hành trả về cấp đỉnh (trong trường hợp này ngoại lệ trở thành lỗi sai)
msgString là giá trị chuỗi mà độc lập với bất kỳ tham số nào là một phần của thông
báo Chuỗi có thể chưá vị trí tham số số dạng '%n' , n là số nguyên từ 0 đến 9
msgParams là một trong các đối tượng bất kỳ của Maple mà thay thế cho vị trí tham số
số trong msgString
Nếu không có msgString, error hiển thị ngoại lệ gần đây nhât
Lệnh error tính toán các đối của nó và tạo ra một đối tượng ngoại lệ, điều mà dãy
biểu thức theo các phần tử sau:
− Tên của thủ tục mà ngoại lệ hiển thị Nếu ngoại lệ hiển thỉ ở cấp đỉnh thì hằng
Trong msgString, tham số số được dùng nắm giữ các giá trị thực và tên
Mỗi tham số số gồm ký hiệu phần trăm "%", theo sau bởi dấu trừ "-", sau là một hoặc nhiều ký số chỉ định bởi n Tại thời điểm thông báo hiển thị tham số msgParam thứ n
được thay thế cho tham số số
Một tham số số dạng %n sẽ hiển thị cho msgParam thứ n trong lprint
Một tham số số dạng %-n sẽ hiển thị cho msgParam thứ n, giả thiết cho số nguyên Maple, trong dạng thứ tự ví dụ, 2 hiển thị "2nd"
Tham số đặc biệt, %0, sẽ hiển thị mọi msgParams, phân cách bởi dấu phẩy và ký tự
trắng
Trong Maple V Release 5.1 và trước đó, dùng hàm ERROR Đây là phiên bản cũ nhưng vẫn còn trong Maple 7
Trang 22II LẬP TRÌNH VỚI MODULE
Cú pháp :
module() export eseq; local lseq; global gseq; option optseq; description desc; BODY end module
Tham số
eseq - dãy biểu thức xuất ra
lseq - dãy biểu thức địa phương
gseq - dãy biểu thức toàn cục
optseq – dãy biểu thức lựa chọn desc
Cú pháp của định nghĩa module tương tự như cú pháp định nghĩa procedure Một định nghĩa module bắt đầu với một từ khoá module, theo sau là cặp dấu ngoặc, sau đó không hoặc nhiều câu lệnh, và kết thúc là từ khoá end hoặc end module Vì vậy, module ngắn nhất có thể là module() end
Như procedure, một module có thể gồm vài câu lệnh khai báo lựa chọn Như lệnh local, global, option, và description giống như trong procedure
Một module có thể hiểu như tập hợp các liên kết tên Một vài liên kết này được truy xuất cho mã Maple ngoài module, sau khi module đã được xây dựng; đó là các
``export'' của module
Một liên kết tên địa phương khác trong module là chỉ truy xuất tức thời của module, tức trong phạm vi thân module Có những biến địa phương khai báo hoặc rõ ràng trong khai báo địa phương của module, hoặc ẩn thông suốt trong phạm vi ẩn của module
Tất cả các tên khác xảy ra trong module là hoặc toàn cục hoặc tham số hoặc tên địa phương giới hạn trong phạm vi Biến xuất hiện trong module có thể là toàn cục nếu được khai báo rõ ràng trong global của module, hay thông qua luật phạm vi ẩn của Maple
Mỗi module có một thân gồm không hoặc nhiều lệnh tuần tự Những câu lệnh này được dùng xác định các giá trị ban đầu cho việc xuất các phần tử của module, và để hoàn thành các tính toán bất kỳ trong suốt module
Việc lựa chọn tên trong thân module, và liên kết của chúng, tạo thành phạm vi từ vựng đầy đủ Module và procedure có thể lồng tương hỗ nhau và tùy ý
- Biến toàn cục: được khai báo với từ khóa global theo sau một hay nhiều ký hiệu
- Biến địa phương: được khai báo với từ khóa local theo sau một hay nhiều ký hiệu
- Export biến địa phương: Dùng từ khóa export theo sau là dãy ký hiệu không rỗng (biến địa phương) Để truy xuất ta dùng :- theo cú pháp tênmodule:- tênkýhiệu khai báo
sau export
Trang 23- Tham số module: nhƣ đã biết module không cần tham số, nhƣng rất có ích khi viết một
module tiến hóa mà dùng một vài tham số:
- Dùng module để cài đặt package:
- Dùng Module để mô hình hóa đối tƣợng:
+ Lệnh bẫy lỗi try :