Lab 4: การสร้างฐานความรู้ด้วย SWI-Prolog

เรื่อง: ความสัมพันธ์ในครอบครัว (Family Relations)


วัตถุประสงค์การเรียนรู้

  1. เข้าใจหลักการของ Predicate Logic และการนำไปใช้ใน Prolog
  2. สามารถสร้าง Facts (ข้อเท็จจริง) เพื่อแทนความรู้พื้นฐาน
  3. สามารถสร้าง Rules (กฎ) เพื่อสร้างความสัมพันธ์ที่ซับซ้อน
  4. สามารถ Query (สอบถาม) ฐานความรู้เพื่อหาคำตอบ

ทฤษฎีเบื้องต้น

Predicate Logic คืออะไร?

Predicate Logic (ตรรกศาสตร์เพรดิเคต) เป็นระบบตรรกะที่ใช้แทนความรู้และการให้เหตุผล ประกอบด้วย:

โครงสร้างของ Prolog

โปรแกรม Prolog ประกอบด้วย 2 ส่วนหลัก:

  1. Facts (ข้อเท็จจริง): ข้อความที่เป็นจริงเสมอ
  2. Rules (กฎ): ข้อความที่เป็นจริงเมื่อเงื่อนไขเป็นจริง

การติดตั้ง SWI-Prolog

Windows

  1. ดาวน์โหลดจาก https://www.swi-prolog.org/download/stable
  2. รันไฟล์ติดตั้งและทำตามขั้นตอน

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install swi-prolog

macOS

brew install swi-prolog

ตรวจสอบการติดตั้ง

swipl --version

ส่วนที่ 1: Facts (ข้อเท็จจริง)

Facts คือข้อความที่ระบุความจริงพื้นฐานในฐานความรู้ มีรูปแบบดังนี้:

predicate(argument1, argument2, ...).

1.1 กำหนดเพศ (Gender)

% === Facts: เพศของบุคคล ===
% male(X) หมายถึง X เป็นเพศชาย
male(somchai).
male(somsak).
male(somyot).
male(prasit).
male(prayut).

% female(X) หมายถึง X เป็นเพศหญิง
female(somying).
female(somporn).
female(mali).
female(malee).
female(manee).

1.2 กำหนดความสัมพันธ์พ่อแม่-ลูก (Parent-Child)

% === Facts: ความสัมพันธ์พ่อแม่-ลูก ===
% parent(X, Y) หมายถึง X เป็นพ่อหรือแม่ของ Y

% รุ่นที่ 1 (ปู่ย่า ตายาย)
parent(somchai, somsak).      % สมชาย เป็นพ่อของ สมศักดิ์
parent(somchai, somporn).     % สมชาย เป็นพ่อของ สมพร
parent(somying, somsak).      % สมหญิง เป็นแม่ของ สมศักดิ์
parent(somying, somporn).     % สมหญิง เป็นแม่ของ สมพร

parent(prasit, mali).         % ประสิทธิ์ เป็นพ่อของ มะลิ
parent(malee, mali).          % มาลี เป็นแม่ของ มะลิ

% รุ่นที่ 2 (พ่อแม่)
parent(somsak, somyot).       % สมศักดิ์ เป็นพ่อของ สมยศ
parent(somsak, manee).        % สมศักดิ์ เป็นพ่อของ มานี
parent(mali, somyot).         % มะลิ เป็นแม่ของ สมยศ
parent(mali, manee).          % มะลิ เป็นแม่ของ มานี

parent(somporn, prayut).      % สมพร เป็นแม่ของ ประยุทธ์

แผนภาพครอบครัว

                    ┌─────────────────┐
         ┌─────────┤   รุ่นที่ 1     ├─────────┐
         │         └─────────────────┘         │
         │                                     │
    ┌────┴────┐                          ┌────┴────┐
    │ สมชาย   │                          │ ประสิทธิ์│
    │ (ชาย)  │                          │ (ชาย)   │
    └────┬────┘                          └────┬────┘
         │  แต่งงาน                           │  แต่งงาน
    ┌────┴────┐                          ┌────┴────┐
    │ สมหญิง  │                          │  มาลี   │
    │ (หญิง) │                          │ (หญิง)  │
    └────┬────┘                          └────┬────┘
         │                                    │
         ├────────────────┬───────────────────┤
         │                │                   │
    ┌────┴────┐     ┌────┴────┐         ┌────┴────┐
    │ สมศักดิ์ │     │  สมพร   │         │  มะลิ   │
    │ (ชาย)  │     │ (หญิง)  │         │ (หญิง) │
    └────┬────┘     └────┬────┘         └────┬────┘
         │               │                   │
         └───────────────┼───────────────────┘
                   แต่งงาน│
                         │
              ┌──────────┴──────────┐
              │                     │
         ┌────┴────┐          ┌────┴────┐
         │ สมยศ    │          │  มานี   │
         │ (ชาย)  │          │ (หญิง) │
         └─────────┘          └─────────┘
         
    สมพร ─────────┬──────────
                  │
            ┌────┴────┐
            │ ประยุทธ์ │
            │ (ชาย)   │
            └─────────┘

ส่วนที่ 2: Rules (กฎ)

Rules คือข้อความที่กำหนดความสัมพันธ์ใหม่จาก Facts หรือ Rules อื่น มีรูปแบบดังนี้:

head :- body.

อ่านว่า "head เป็นจริง ถ้า body เป็นจริง"

2.1 กฎพื้นฐาน: พ่อ และ แม่

% === Rules: พ่อ และ แม่ ===

% father(X, Y) - X เป็นพ่อของ Y
% พ่อ คือ ผู้ปกครองที่เป็นเพศชาย
father(X, Y) :- 
    parent(X, Y), 
    male(X).

% mother(X, Y) - X เป็นแม่ของ Y  
% แม่ คือ ผู้ปกครองที่เป็นเพศหญิง
mother(X, Y) :- 
    parent(X, Y), 
    female(X).

คำอธิบาย:

2.2 กฎพี่น้อง (Sibling)

% === Rules: พี่น้อง ===

% sibling(X, Y) - X และ Y เป็นพี่น้องกัน
% พี่น้อง คือ บุคคลที่มีพ่อแม่คนเดียวกัน (แต่ไม่ใช่คนเดียวกัน)
sibling(X, Y) :- 
    parent(P, X), 
    parent(P, Y), 
    X \= Y.

% brother(X, Y) - X เป็นพี่ชาย/น้องชายของ Y
brother(X, Y) :- 
    sibling(X, Y), 
    male(X).

% sister(X, Y) - X เป็นพี่สาว/น้องสาวของ Y
sister(X, Y) :- 
    sibling(X, Y), 
    female(X).

คำอธิบาย:

2.3 กฎปู่ย่าตายาย (Grandparent)

% === Rules: ปู่ย่าตายาย ===

% grandparent(X, Y) - X เป็นปู่/ย่า/ตา/ยาย ของ Y
% ปู่ย่าตายาย คือ พ่อแม่ของพ่อแม่
grandparent(X, Y) :- 
    parent(X, Z), 
    parent(Z, Y).

% grandfather(X, Y) - X เป็นปู่/ตา ของ Y
grandfather(X, Y) :- 
    grandparent(X, Y), 
    male(X).

% grandmother(X, Y) - X เป็นย่า/ยาย ของ Y
grandmother(X, Y) :- 
    grandparent(X, Y), 
    female(X).

2.4 กฎลุงป้าน้าอา (Uncle/Aunt)

% === Rules: ลุง ป้า น้า อา ===

% uncle(X, Y) - X เป็นลุง/อา ของ Y
% ลุง/อา คือ พี่ชาย/น้องชาย ของพ่อหรือแม่
uncle(X, Y) :- 
    parent(P, Y),      % P เป็นพ่อหรือแม่ของ Y
    sibling(X, P),     % X เป็นพี่น้องกับ P
    male(X).           % X เป็นเพศชาย

% aunt(X, Y) - X เป็นป้า/น้า ของ Y
% ป้า/น้า คือ พี่สาว/น้องสาว ของพ่อหรือแม่
aunt(X, Y) :- 
    parent(P, Y),      % P เป็นพ่อหรือแม่ของ Y
    sibling(X, P),     % X เป็นพี่น้องกับ P
    female(X).         % X เป็นเพศหญิง

2.5 กฎลูกพี่ลูกน้อง (Cousin)

% === Rules: ลูกพี่ลูกน้อง ===

% cousin(X, Y) - X และ Y เป็นลูกพี่ลูกน้องกัน
% ลูกพี่ลูกน้อง คือ ลูกของลุง/ป้า/น้า/อา
cousin(X, Y) :- 
    parent(PX, X),     % PX เป็นพ่อหรือแม่ของ X
    parent(PY, Y),     % PY เป็นพ่อหรือแม่ของ Y
    sibling(PX, PY).   % PX และ PY เป็นพี่น้องกัน

2.6 กฎบรรพบุรุษ (Ancestor) - Recursive Rule

% === Rules: บรรพบุรุษ (Recursive) ===

% ancestor(X, Y) - X เป็นบรรพบุรุษของ Y
% Base case: พ่อแม่เป็นบรรพบุรุษ
ancestor(X, Y) :- 
    parent(X, Y).

% Recursive case: บรรพบุรุษของพ่อแม่ก็เป็นบรรพบุรุษ
ancestor(X, Y) :- 
    parent(Z, Y), 
    ancestor(X, Z).

คำอธิบาย:

2.7 กฎลูกหลาน (Descendant)

% === Rules: ลูกหลาน ===

% descendant(X, Y) - X เป็นลูกหลานของ Y
descendant(X, Y) :- 
    ancestor(Y, X).

ส่วนที่ 3: โค้ดโปรแกรมเต็ม

สร้างไฟล์ family.pl และใส่โค้ดต่อไปนี้:

% ============================================
% ฐานความรู้ครอบครัว (Family Knowledge Base)
% ============================================

% === FACTS ===

% --- เพศของบุคคล ---
male(somchai).
male(somsak).
male(somyot).
male(prasit).
male(prayut).

female(somying).
female(somporn).
female(mali).
female(malee).
female(manee).

% --- ความสัมพันธ์พ่อแม่-ลูก ---
% รุ่นที่ 1
parent(somchai, somsak).
parent(somchai, somporn).
parent(somying, somsak).
parent(somying, somporn).
parent(prasit, mali).
parent(malee, mali).

% รุ่นที่ 2
parent(somsak, somyot).
parent(somsak, manee).
parent(mali, somyot).
parent(mali, manee).
parent(somporn, prayut).

% === RULES ===

% --- พ่อ และ แม่ ---
father(X, Y) :- parent(X, Y), male(X).
mother(X, Y) :- parent(X, Y), female(X).

% --- พี่น้อง ---
sibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.
brother(X, Y) :- sibling(X, Y), male(X).
sister(X, Y) :- sibling(X, Y), female(X).

% --- ปู่ย่าตายาย ---
grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
grandfather(X, Y) :- grandparent(X, Y), male(X).
grandmother(X, Y) :- grandparent(X, Y), female(X).

% --- ลุง ป้า น้า อา ---
uncle(X, Y) :- parent(P, Y), sibling(X, P), male(X).
aunt(X, Y) :- parent(P, Y), sibling(X, P), female(X).

% --- ลูกพี่ลูกน้อง ---
cousin(X, Y) :- parent(PX, X), parent(PY, Y), sibling(PX, PY).

% --- บรรพบุรุษ (Recursive) ---
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- parent(Z, Y), ancestor(X, Z).

% --- ลูกหลาน ---
descendant(X, Y) :- ancestor(Y, X).

% --- สายเลือดเดียวกัน ---
related(X, Y) :- ancestor(Z, X), ancestor(Z, Y), X \= Y.

ส่วนที่ 4: การใช้งาน SWI-Prolog

4.1 เริ่มต้นใช้งาน

# เปิด SWI-Prolog
swipl

# โหลดไฟล์ฐานความรู้
?- [family].
% หรือ
?- consult('family.pl').

4.2 ตัวอย่างการ Query

Query แบบ Yes/No (ตรวจสอบความจริง)

% ถาม: สมชายเป็นพ่อของสมศักดิ์หรือไม่?
?- father(somchai, somsak).
% ตอบ: true.

% ถาม: มะลิเป็นแม่ของสมยศหรือไม่?
?- mother(mali, somyot).
% ตอบ: true.

% ถาม: สมศักดิ์และสมพรเป็นพี่น้องกันหรือไม่?
?- sibling(somsak, somporn).
% ตอบ: true.

Query แบบหาค่า (ใช้ตัวแปร)

% ถาม: ใครเป็นพ่อของสมศักดิ์?
?- father(X, somsak).
% ตอบ: X = somchai.

% ถาม: สมชายเป็นพ่อของใครบ้าง?
?- father(somchai, X).
% ตอบ: X = somsak ;
%       X = somporn.
% (กด ; เพื่อดูคำตอบถัดไป, กด . เพื่อหยุด)

% ถาม: ใครเป็นปู่ของสมยศ?
?- grandfather(X, somyot).
% ตอบ: X = somchai ;
%       X = prasit.

% ถาม: หาพี่น้องทั้งหมดของสมศักดิ์
?- sibling(X, somsak).
% ตอบ: X = somporn.

% ถาม: หาบรรพบุรุษทั้งหมดของสมยศ
?- ancestor(X, somyot).
% ตอบ: X = somsak ;
%       X = mali ;
%       X = somchai ;
%       X = somying ;
%       X = prasit ;
%       X = malee.

Query แบบซับซ้อน

% ถาม: หาคนที่เป็นทั้งพ่อและมีลูกเป็นเพศหญิง
?- father(X, Y), female(Y).
% ตอบ: X = somchai, Y = somporn ;
%       X = somsak, Y = manee.

% ถาม: หาย่าของมานี
?- grandmother(X, manee), mother(X, Father), father(Father, manee).
% หรือแบบง่าย
?- grandmother(X, manee).
% ตอบ: X = somying ;
%       X = malee.

% ถาม: ใครมีความสัมพันธ์เป็นลูกพี่ลูกน้องกับประยุทธ์?
?- cousin(X, prayut).
% ตอบ: X = somyot ;
%       X = manee.

4.3 คำสั่งที่มีประโยชน์

% ดูข้อมูลทั้งหมดของ predicate
?- listing(parent).

% หาคำตอบทั้งหมดในครั้งเดียว
?- findall(X, father(somchai, X), Children).
% ตอบ: Children = [somsak, somporn].

% หาคำตอบไม่ซ้ำ
?- setof(X, ancestor(X, somyot), Ancestors).
% ตอบ: Ancestors = [malee, mali, prasit, somchai, somsak, somying].

% ออกจากโปรแกรม
?- halt.

ส่วนที่ 5: แบบฝึกหัด

แบบฝึกหัดที่ 1: เพิ่ม Facts

เพิ่มสมาชิกใหม่ในครอบครัว:

% เขียนคำตอบของคุณที่นี่:
male(wichai).
female(nida).
female(wanida).
parent(somyot, wichai).
parent(somyot, wanida).
parent(nida, wichai).
parent(nida, wanida).

แบบฝึกหัดที่ 2: สร้าง Rules ใหม่

สร้างกฎต่อไปนี้:

2.1 หลาน (Grandchild)

% grandchild(X, Y) - X เป็นหลานของ Y
grandchild(X, Y) :- grandparent(Y, X).

2.2 ลูกชาย/ลูกสาว (Son/Daughter)

% son(X, Y) - X เป็นลูกชายของ Y
son(X, Y) :- parent(Y, X), male(X).

% daughter(X, Y) - X เป็นลูกสาวของ Y
daughter(X, Y) :- parent(Y, X), female(X).

2.3 ปู่/ตา ฝั่งพ่อ และ ฝั่งแม่

% paternal_grandfather(X, Y) - X เป็นปู่ (พ่อของพ่อ) ของ Y
paternal_grandfather(X, Y) :- 
    father(X, F), 
    father(F, Y).

% maternal_grandfather(X, Y) - X เป็นตา (พ่อของแม่) ของ Y
maternal_grandfather(X, Y) :- 
    father(X, M), 
    mother(M, Y).

แบบฝึกหัดที่ 3: Query

เขียน Query เพื่อหาคำตอบต่อไปนี้:

  1. หาแม่ของมานี

    ?- mother(X, manee).
    
  2. หาว่าใครเป็นลูกหลานของสมชาย

    ?- descendant(X, somchai).
    
  3. ตรวจสอบว่าประยุทธ์และสมยศเป็นลูกพี่ลูกน้องกันหรือไม่

    ?- cousin(prayut, somyot).
    
  4. หาป้าของมานี

    ?- aunt(X, manee).
    
  5. หาคนที่มีความเกี่ยวข้องกัน (related) กับสมยศทั้งหมด

    ?- findall(X, related(X, somyot), RelatedPeople).
    

แบบฝึกหัดที่ 4: สร้างฐานความรู้ใหม่

สร้างฐานความรู้ครอบครัวของตัวเอง โดยมีสมาชิกอย่างน้อย 10 คน ครอบคลุม 3 รุ่น


ส่วนที่ 6: สรุป

ตารางเปรียบเทียบ Facts vs Rules

ลักษณะ Facts Rules
รูปแบบ predicate(args). head :- body.
ความหมาย ข้อเท็จจริงพื้นฐาน ความสัมพันธ์ที่อนุมานได้
ตัวอย่าง parent(somchai, somsak). father(X,Y) :- parent(X,Y), male(X).

Operators ที่สำคัญ

Operator ความหมาย ตัวอย่าง
:- if (ถ้า) A :- B. (A จริง ถ้า B จริง)
, and (และ) A, B (A และ B)
; or (หรือ) A ; B (A หรือ B)
\= ไม่เท่ากับ X \= Y
= เท่ากับ (unification) X = Y

เคล็ดลับการเขียน Prolog

  1. ใช้ชื่อที่มีความหมาย: เช่น parent, father, mother แทน p, f, m
  2. Comment โค้ด: ใช้ % สำหรับ comment บรรทัดเดียว
  3. ระวัง Recursive: ต้องมี Base case เสมอ
  4. ทดสอบทีละส่วน: Query ทดสอบ Facts ก่อน แล้วค่อยทดสอบ Rules

เอกสารอ้างอิง

  1. SWI-Prolog Documentation: https://www.swi-prolog.org/pldoc/
  2. Learn Prolog Now!: http://www.learnprolognow.org/
  3. Prolog Tutorial: https://www.tutorialspoint.com/prolog/

จัดทำเพื่อการศึกษา - วิชาปัญญาประดิษฐ์/ระบบผู้เชี่ยวชาญ