Bước giải là một bước suy diễn ra sự kiện mới từ một số sự kiện đã biết, thuộc một trong các dạng suy diễn sau:
[1] Deduce_From3s: suy ra các sự kiện loại 2 từ các sự kiện loại 3.
[2] Deduce_From43s: suy ra các sự kiện mới loại 3 từ các sự kiện loại 3 và 4 bằng
cách thay thế các biến trong sự kiện loại 3 vào sự kiện loại 4.
[3] Deduce_From53s: suy ra các sự kiện mới loại 3, 4, 5 từ các sự kiện loại 3 và
53
[4] Deduce_From45s: suy ra các sự kiện mới loại 3 từ các sự kiện loại 4 và 5 bằng
cách giải hệ phương trình.
[5] Deduce_From8s: suy ra các sự kiện loại 7 từ các sự kiện loại 8.
[6] Deduce_From983s: suy ra các sự kiện loại 3, 8 từ các sự kiện loại 3, 8, 9 bằng
cách thế các biến trong sự kiện loại 8 (hay sự kiện loại 3) vào sự kiện loại 9.
[7] Deduce_Objects: thực hiện suy diễn và tính toán bên trong cấu trúc của từng
đối tượng. Các đối tượng tham gia vào bước giải có khả năng thực hiện các hành vi nhất định để phát sinh sự kiện mới, thực hiện suy diễn tính toán trên các thuộc tính của đối tượng, bản thân đối tượng hay các đối tượng liên quan được thiết lập trên nền của đối tượng.
[8] Deduce_From9s: suy ra các sự kiện loại 2, 3, 6, 7, 8 từ các sự kiện loại 9 bằng
cách thực hiện tính toán hàm.
[9] Deduce_Rules: dò tìm luật có thể áp dụng được.
[10] Deduce_Funcs: dò tìm hàm có thể áp dụng được.
[11] Deduce_EqsGoal: giải hệ phương trình đơn giản gồm n phương trình n ẩn.
Các bước giải bên trong Deduce_Objects
Deduce_ObjProp: sinh ra sự kiện mới từ các tính chất nội tại bên trong đối
tượng liên quan đến các thuộc tính của đối tượng.
Deduce_OconstructRela: sinh ra sự kiện mới loại 3 bằng cách thực hiện tính
toán các quan hệ trên cấu trúc thiết lập.
Deduce_ObjRules: dò tìm luật suy diễn có thể áp dụng được bên trong cấu trúc
đối tượng.
Deduce_ObjRela1: Áp dụng một quan hệ tính toán f bằng cách thế các biến
trong f mà có mặt trong tập sự kiện loại 2 và loại 3. Dạng suy luận này chỉ có thể suy ra sự kiện mới khi ta có điều kiện: f có đúng một biến không có mặt trong tập sự kiện loại 2.
Deduce_ObjRela21: Áp dụng một quan hệ tính toán f chứa 2 biến không nằm
trong tập sự kiện loại 2 và có khả năng kết hợp với một sự kiện loại 4 hoặc 5 cũng có 2 biến như trên để giải hệ phương trình sinh ra sự kiện mới loại 2, 3.
54
Deduce_ObjRela22: Như Deduce_ObjRela21 với f chứa 3 biến không nằm
trong tập sự kiện loại 2 và có khả năng kết hợp với 2 sự kiện loại 4 hoặc 5 cũng có 3 biến như trên để giải hệ phương trình sinh ra sự kiện mới loại 2, 3.
Deduce_ObjRela2: Áp dụng một quan hệ tính toán f trên một số sự kiện loại
2 và loại 3 để suy ra một sự kiện mới loại 3, 4 hoặc 5, bằng cách thay thế các biến trong f mà có mặt trong tập sự kiện loại 2, 3, rồi tính một biến theo các biến còn lại trong f.
Deduce_ObjRela3: Thay thế một biến trong f có mặt trong sự kiện 4, 5 vào
các sự kiện này để tạo ra các sự kiện mới có số biến ít hơn.
Deduce_ObjFunc: Thực hiện tính toán các hàm thiết lập trên các thuộc tính
hay các đối tượng nền xác định của đối tượng (nếu có).
Ví dụ 3.15: Ví dụ minh họa các bước suy diễn (bước giải) trong quá trình giải toán
[1] {d1.f=(x+y+9 = 0), a = [6,-3], O.S=3 } {d1.f, a, O.S} (Deduce_From3s).
[2] {O.a = DOAN[C, D], O.a = m} { DOAN[C,D] = m} (Deduce_From43s).
[3] {O1.a = O1.b+1/2*(O1.c), O1.b = 3} {O1.a-3-1/2*(O1.c) = 0}
(Deduce_From53s). [4] {a+2b = -2, a = b} {b = -2/3, a = -2/3} (Deduce_From45s). [5] {KHOANGCACH(A, d) = 4} {KHOANGCACH(A, d)} (Deduce_From8s). [6] {M=TRUNGDIEM(A, B), M=[2,-1] } {TRUNGDIEM(A, B)=[2,-1]} (Deduce_From983s).
[7] { f:= ["DIEM", "GIAODIEM", ["DUONGTHANG", "DOAN"], {"doi
xung"}], K = GIAODIEM(d,DOAN[M,K]), d, d.f = (2*x+y-4 = 0), DOAN[M,K],
DOAN[M,K].f = (-x-3+2*y = 0)} {GIAODIEM(d,DOAN[M,K]),
GIAODIEM(d,DOAN[M,K]) = [1, 2], K = [1, 2]} (Deduce_From9).
[8] { f:= ["xac_dinh", [dt1, dt2, W], ["DUONGTHANG", "DOAN", "DIEM"], [{["THUOC", W, dt1], ["THUOC", W, dt2]}, {W = GIAODIEM(dt1,dt2)}], ""],
["THUOC", K, DOAN[M,K]], ["THUOC", K, d]} {K =
55
[9] { f:= ["DIEM", "DOIXUNG", ["DIEM", "DIEM"], {}], Q, P, P = [2, 5], Q =
[5, 1]} {DOIXUNG(P,Q), DOIXUNG(P,Q) = [8, -3]} (Deduce_Funcs).
[10]{DOAN[M,K]} {["THUOC", M, DOAN[M,K]], ["THUOC", K,
DOAN[M,K]]} (Deduce_ObjProp).
[11]{ (O1.a)^2 = (O1.b)^2+(O1.c)^2} {["VUONG", O1, A], ["VUONG",
O1.b, O1.c], O1.GocA = 1/2*Pi, ["VUONG", VECTO(A,B), VECTO(A,C)]}]} (Deduce_ObjRules).
[12]{ f:= [O1.S = 1/2*abs((B.x-(A.x))*(C.y-(A.y))-(C.x-(A.x))*(B.y-(A.y)))],
{C.y = -3, B.y = 1, A.y = 5, C.x = 0, A.x = 2, B.x = 5}, {O1.S = 16}]} {}
(Deduce_OConstructRela).
[13]{ f:= [" begin_relation 0", 1, {O1.GocP, O1.GocN, O1.GocM}, 1, {},
O1.GocM+O1.GocN+O1.GocP = Pi, 2], O1.GOC[N,M,P] = 1/4*Pi,
O1.GOC[P,N,M] = 1/3*Pi} {O1.GocP = 5/12*Pi} (Deduce_ObjRela1).
[14]{ f:= ["begin_relation 0", 1, {O1.GocA, O1.GocB, O1.GocC}, 1, {},
O1.GocA+O1.GocB+O1.GocC = Pi, 2], O1.GocB+2*(O1.GocC) = 5/12*Pi,
O1.GocA = 1/4*Pi } {O1.GocB = 13/12*Pi, O1.GocC = -1/3*Pi}
(Deduce_ObjRela21).
[15]{ f:= [" begin_relation 10", 1, {O1.a, O1.c, O1.p, O1.b}, 1, {}, 2*(O1.p) =
O1.a+O1.b+O1.c, 4], {O1.c = 4/11*(O1.a)+4/11*(O1.p), O1.a-3-1/2*(O1.c) = 0,
O1.b = 3 } {O1.a = 5, O1.c = 4, O1.p = 6} (Deduce_ObjRela22).
[16]{P = [2, 5], Q = [5, 1], ["THUOC", P, d], KHOANGCACH(Q,d) = 3 } {
d.f = (x+24/7*y-134/7 = 0) } (Deduce_EqsGoal) 3.4.3 Heuristic
Việc áp dụng các qui tắc heuristic là rất quan trọng trong quá trình tìm kiếm suy diễn và tính toán. Các heuristic giúp ta có thể tìm được lời giải tốt hơn, ngắn gọn hơn, nhanh hơn, cho lời giải tự nhiên gần với cách suy nghĩ và hành động của con người hơn nhờ vào việc áp dụng những kinh nghiệm của con người trong quá trính giải các bài toán trong thực tế. Trong một số thuật toán, ta thường dùng bổ sung các thủ thuật heuristic ở những khâu lựa chọn nhất định. Dưới đây là một số qui tắc heuristic có thể áp dụng được:
56
Thực hiện hành động dựa trên một cấu trúc thứ tự hợp lý của không gian khảo
sát nhằm nhanh chóng đạt được lời giải tốt:
Ưu tiên áp dụng theo thứ tự bước giải từ Deduce_From3s,
Deduce_From43s, Deduce_From53s, Deduce_From45s, Deduce_From8s, Deduce_From983s.
Trong các bước giải bên trong Deduce_Objects, ưu tiên áp dụng các dạng
Deduce_ObjProp, Deduce_ObjRela1, Deduce_ObjRela21,
Deduce_ObjRela22, Deduce_ObjRules.
Trong các bước giải có liên quan đến hàm, ưu tiên Deduce_From9s.
Nếu mục tiêu là hàm và có thể tính toán được thì thực hiện tính toán mà không
cần thông qua các bước giải trên.
Sử dụng heuristic trong việc dò tìm luật suy diễn có thể áp dụng được (bước
giải Deduce_Rules): trong quá trình giải toán ta thường dùng một tập luật rất lớn, nếu vét cạn hết tất cả các luật trong tập luật này thì chương trình sẽ chạy chậm, tốn nhiều thời gian. Do đó ta cần áp dụng một số qui tắc heuristic thực hiện vét cạn thông minh, tức là ta chỉ tìm những luật có khả năng hướng đến mục tiêu cần tìm Các qui tắc có thể kể đến là:
Giới hạn lại không gian tìm kiếm xuất phát từ mục tiêu bài toán hoặc thực
hiện một kiểu dò tìm đặc biệt dựa vào đặc thù của bài toán để nhanh chóng tìm ra mục tiêu.
Chỉ xét các luật có khả năng áp dụng
Ưu tiên những luật quen thuộc thường dùng.
Sử dụng heuristic trong việc dò tìm hàm có thể áp dụng được thì ưu tiên các
hàm hướng đến mục tiêu.
Trong quá trình thực hiện áp dụng luật có thể loại bớt những tổ hợp không cần
thiết để thuật toán thực hiện nhanh hơn.
Trong 1 tổ hợp có sự xuất hiện nhiều lần của 1 đối tượng.
Nếu trong tổ hợp có đối tượng cấp cao thì loại những tổ hợp mà không có
57
Ưu tiên sử dụng các qui tắc xác định đối tượng và các thuộc tính của đối
tượng.
Sử dụng các qui tắc phát sinh đối tượng mới để bổ sung thêm các sự kiện cần
thiết nhằm hỗ trợ khi bài toán chưa giải được. Trong đó, ưu tiên tạo ra các đối tượng có liên quan đến đối tượng đang có và liên quan đến mục tiêu nhất.
Nếu không thể phát sinh ra sự kiện mới hay đối tượng mới ta có thể đặt tham
biến rồi giải phương trình hay hệ phương trình.
Nếu có tham số cần được xác định thì ưu tiên sử dụng các qui tắc tính toán và
các tính chất của phép toán.
3.5 CÁC VẤN ĐỀ KỸ THUẬT
Xây dựng một hệ giải toán dựa trên tri thức là rất phức tạp bao gồm việc thiết kế một cơ sở tri thức cho hệ thống tương tự như tri thức thực của con người, và một động cơ suy diễn để giải quyết vấn đề dựa trên tri thức, trong đó đòi hỏi có những kinh nghiệm cũng như tư duy của con người trong việc giải các bài toán tự động. Vì vậy, cần phải trang bị một phương pháp và thuật giải tốt, khả thi để máy tính có thể giải toán một cách hiệu quả.
Chiến lược suy diễn cơ bản được sử dụng ở thuật toán trên là phương pháp suy diễn tiến/lùi kết hợp với các qui tắc heuristic. Ở một số bước giải, ta không chỉ áp dụng các luật suy diễn mà còn thực hiện các tính toán thích hợp hoặc xử lý bên trong mỗi đối tượng. Trong phần này, chúng ta sẽ tập trung vào việc giải quyết các vấn đề kỹ thuật gặp phải trong các bước thực hiện thuật toán đã được đề cập ở trên như:
Vấn đề thứ nhất: vấn đề về sự hợp nhất giữa các loại sự kiện.
Vấn đề thứ hai: vấn đề về quá trình tìm kiếm và suy diễn trên thành phần tri
thức hàm.
Vấn đề thứ ba: vấn đề về quá trình tìm kiếm và giải phương trình, hệ phương
trình.
3.5.1 Hợp nhất sự kiện
Vấn đề hợp nhất sự kiện là một trong những vấn đề quan trọng nhất trong việc xây dựng hệ giải toán thông minh.
58
Định nghĩa 3.3: Ta nói 2 sự kiện fact1 và fact2 là hợp nhất khi:
(1) fact1 = fact2.
(2)Nếu fact1 <> fact2 thì phải thỏa các điều kiện dưới đây:
- fact1 và fact2 là cùng loại k (k=[1..11]), và
- Kiểm tra giá trị k:
Nếu k=2:
[fact1[1], fact1[2..nops(fact1)]] = [fact2[1], fact2[2..nops(fact2)]].
Nếu k=3:
lhs(fact1) = lhs(fact2) và compute(rhs(fact1)) = compute(rhs(fact2)).
Nếu k=4:
(lhs(fact1) = lhs(fact2) và rhs(fact1) = rhs(fact2)) hay (lhs(fact1) = rhs(fact2) và rhs(fact1) = lhs(fact2)).
Nếu k=5:
evalb(simplify(expand(lhs(fact1)-rhs(fact1)- lhs(fact2)+rhs(fact2))) = 0) hay evalb(simplify(expand(lhs(fact1)-rhs(fact1)+ lhs(fact2)-rhs(fact2))) = 0).
Nếu k=6:
Quan hệ trong sự kiện fact1 có tính “đối xứng” và
[fact1[1], fact1[2..nops(fact1)]] = [fact2[1], fact2[2..nops(fact2)]].
Nếu k=7:
Hàm trong sự kiện fact1 có tính “đối xứng” và
[fact1[1], fact1[2..nops(fact1)]] = [fact2[1], fact2[2..nops(fact2)]].
Nếu k=8:
lhs(fact1) = lhs(fact2) và compute(rhs(fact1)) = compute(rhs(fact2))
hay:
Hàm trong sự kiện fact1 có tính “đối xứng” và
[lhs(fact1[1], fact1[2..nops(fact1)])] = [lhs(fact2[1], fact2[2..nops(fact2)])]
và compute(rhs(fact1)) = compute(rhs(fact2)).
Nếu k=9:
(lhs(fact1) = lhs(fact2) và Hàm trong sự kiện fact1 có tính “đối xứng” và
59
Nếu k=10:
Hàm bên trái trong sự kiện fact1 không đối xứng và
{[lhs(fact1[1], fact1[2..nops(fact1)])] = [lhs(fact2[1], fact2[2..nops(fact2)])}
và [rhs(fact1[1], fact1[2..nops(fact1)])] = [rhs(fact2[1], fact2[2..nops(fact2)])]
hay:
[lhs(fact1[1], fact1[2..nops(fact1)])] = [lhs(fact2[1], fact2[2..nops(fact2)])]
và hàm trong sự kiện fact1 có tính “đối xứng” và
[rhs(fact1[1], fact1[2..nops(fact1)])] = [rhs(fact2[1], fact2[2..nops(fact2)])]
Nếu k=11:
[lhs(fact1[1], fact1[2..nops(fact1)])] = [lhs(fact2[1], fact2[2..nops(fact2)])] và
[rhs(fact1[1], fact1[2..nops(fact1)])] = [rhs(fact2[1], fact2[2..nops(fact2)])]
hay:
[lhs(fact1[1], fact1[2..nops(fact1)])] = [rhs(fact2[1], fact2[2..nops(fact2)])] và
[rhs(fact1[1], fact1[2..nops(fact1)])] = [lhs(fact2[1], fact2[2..nops(fact2)])]
Trong đó các ký hiệu có ý nghĩa như sau:
. . .: một tập hợp.
[. . .]: một danh sách (list).
L[1]: thành phần thứ nhất của danh sách L.
L[i..j]: dãy các thành phần từ vị trí i đến vị trí j trong danh sách L. nops(L): số thành phần của danh sách L.
lhs(eqn): vế trái của đẳng thức <eqn>, rhs(eqn): vế phải của đẳng thức <eqn>,
compute(expr): kết quả tính toán của biểu thức <expr>, expand(expr): khai triển biểu thức <expr>,
simplify(expr): đơn giản biểu thức <expr>,
evalb(expr1 = expr2): đánh giá việc so sánh bằng nhau giữa biểu thức <expr1> và biểu thức <expr2>.
Vấn đề hợp nhất của 6 sự kiện đầu tiên đã được giải quyết trong mô hình COKB, xem tại tài liệu [14], các sự kiện từ loại 7 đến loại 11 được xem xét và giải quyết trong mô
60
hình Funcs-COKB của đề tài này. Đây là 5 loại sự kiện liên quan đến thành phần tri thức hàm của mô hình Funcs-COKB.
Ví dụ 3.26: Ví dụ về sự hợp nhất của các loại sự kiện
Các cặp sự kiện cùng loại được minh họa ở dưới đây thực chất là một. Do đó, chúng có thể hợp nhất lại thành một sự kiện mà thôi.
Loại 1: [Ob1, “TAM_GIAC”] và [Ob1, “TAM_GIAC”]. Loại 2: DOAN[A,B] và DOAN[B,A].
Loại 3: Ob.a = (m+1)2 và Ob.a = m2 + 2*m + 1.
Loại 4: a = b và b = a; Ob1 = Ob2 và Ob2 = Ob1. Loại 5: a2 = b2 + c2 và b2 = a2 – c2.
Loại 6: a // b và b // a.
Loại 7: KHOANGCACH(A,B) và KHOANGCACH(B,A).
Loại 8: KHOACHCACH(A,B) = (m+1)2 và KHOANGCACH(B,A) = m2 + 2*m + 1.
Loại 9: M = TRUNGDIEM(A,B) và M = TRUNGDIEM(B,A)
Loại 10: DOIXUNG(A,B) = GIAODIEM(d1,d2) và
DOIXUNG(A,B) = GIAODIEM(d2,d1);
Loại 11: KHOANGCACH(A,B)=KHOANGCACH(A,M)+ KHOANGCACH(M,B) và KHOANGCACH(A,M)=KHOANGCACH(A,B) - KHOANGCACH(M,B) 3.5.2 Thuật giải tìm kiếm và suy diễn trên hàm
Vấn đề tiếp theo mà ta gặp phải là vấn đề tìm kiếm và suy diễn trên thành phần tri thức hàm ở bước 4 và bước 6 của thuật toán. Vấn đề đặt ra là: từ các sự kiện đã cho ở giả thiết của bài toán, ta tìm kiếm các hàm có thể sử dụng được để tính toán hoặc sinh ra các sự kiện mới, sau đó cập nhật lại giả thiết của bài toán và lưu lại các bước giải.
Input : Tập các sự kiện giả thiết của bài toán, tập các hàm Output : Tập các sự kiện mới, các bước giải
Bước 1: Tìm kiếm các hàm hướng tới mục tiêu và có thể áp dụng được. FuncsApp:= []; # khởi tạo danh sách các hàm ưu tiên. for func in {danh sách các hàm} do{
61
if (các đối số của hàm có kiểu nằm trong tập các kiểu của các đối tượng xác định and kiểu trả về của hàm có liên quan đến mục tiêu) then
FuncsApp:= [op(FuncsApp),func];
end if
} # end for
Bước 2: Thực hiện tính toán từng hàm
FuncNew:={}; # tập lưu sự kiện mới sinh ra khi tính toán hàm for func in FuncsApp do{
<2.1> Tìm thủ tục tính toán của hàm
<2.2> Tổ hợp các đối tượng xác định trong bài toán có thể áp dụng trên hàm <2.3> for ds to nops(ToHop) do{
<2.3.1> Kiểm tra cặp (func, Tohop[ds]) có được xử lý chưa, nếu có thì quay lại đầu vòng lặp for đầu tiên.
<2.3.2> Lấy giá trị của các đối số
<2.3.3> Truyền cho các đối số hình thức giá trị thực tế tương ứng rồi gọi và thực hiện thủ tục tính toán hàm. Gán kết quả trả về cho FuncNew.
<2.3.4> if FuncNew <> {} then
Phân loại tập sự kiện mới sinh ra rồi cập nhật vào FactSet, Fact_Kinds, lưu lại cặp hàm và tổ hợp tương ứng đã xét, lưu bước giải thực hiện.
end if;
} # end for trong ở <2.3> } # end for ngoài
3.5.3 Thuật giải tìm và giải hệ phương trình
Một vấn đề nữa ta gặp phải trong thuật toán giải toán tự động chính là vấn đề tìm kiếm và giải các hệ phương trình. Vấn đề đặt ra như sau: Từ tập các sự kiện đã cho của bài toán ta phải tìm kiếm các luật, các hàm cũng như là sự kiện có thể áp dụng được để sinh ra các phương trình, từ đó tính toán và suy luận sinh ra các sự kiện mới. Input: Tập các sự kiện, tập các luật, tập các hàm
62
Output: Sinh ra tập sự kiện mới và lưu lại các bước giải. Thuật giải này được thực hiện thông qua các bước như sau: Bước 1: Khởi tạo các biến cần dùng
RuleFunc:= []; # lưu các luật, hàm có thể áp dụng để sinh ra phương trình
Vars := {}; # lưu tất cả các biến
Bước 2: Thực hiện tìm kiếm các luật, hàm hay các sự kiện có khả năng sinh phương trình.
<2.1> find_rule(): Tìm kiếm các luật có thể áp dụng được
<2.2> find_fact8(): Tìm kiếm các sự kiện loại 8 thỏa điều kiện là có ít nhất một biến chưa biết trong tất cả các biến có trong sự kiện loại 8.
<2.3> find_fact9(): tương tự find_fact8() nhưng áp dụng cho các sự kiện loại 9. <2.4> find_fact10(): tương tự như find_fact8() nhưng áp dụng cho các sự kiện loại 10.
<2.5> find_fact3_object(): tìm kiếm sự kiện loại 3 bên trong cấu trúc một object với điều kiện vế trái của sự kiện loại 3 chưa xác định.
Sau mỗi bước, nếu tìm thấy luật, hàm hay sự kiện có thể sinh ra phương trình thì lưu chúng vào RuleFunc và lưu các biến trong luật, hàm hay sự kiện đó vào Vars.
Bước 3: Từ các luật, hàm, sự kiện tìm được ở trên, thực hiện sinh phương trình rồi chọn các hệ phương trình tương ứng để giải.
Vars := [op(Vars)];
Values := Get_Values(Vars); # lấy giá trị của Vars Nếu giá trị của các biến là giá trị đơn
Eqs := {}; # lưu phương trinh for rf to nops(RuleFunc) do
- Sinh phương trình
- Eqs := Eqs union {pt}
- Tìm kiếm trong Eqs những phương trình có thể giải được. - Giải phương trình để có được giá trị của biến chưa biết. - Sau đó loại những phương trình đã giải ra khỏi Eqs.
63
end for;
Nếu giá trị của các biến không phải là giá trị đơn for value in Values do
thực hiện như trường hợp giá trị đơn ở trên với mỗi value.
end for;
3.6CÁC VÍ DỤ MINH HỌA
Bài 1. Trong hệ trục tọa độ Oxy, cho 2 vecto u và v(1,2) cùng vuông góc với vecto n. Viết phương trình đường thẳng d đi qua điểm A(0,1) và có vecto chỉ phương là u.