วันอังคารที่ 1 พฤษภาคม พ.ศ. 2561

โครงสร้าง argument กับ attack : assumption-based argumentation

โพสนี้อยู่ในหมวด เรียนรู้ logic programming + argumentation นะคะ
จากที่โพสก่อนหน้า เราได้สรุปเกี่ยวกับแนวคิดของ abstract argumentation framework ไปแล้ว ซึ่งเป็นไอเดียให้ผู้อ่านพอมองเห็นภาพได้ว่า argumentation คืออะไร ประกอบไปด้วยอะไรบ้าง และเกี่ยวข้องกับงานด้าน reasoning ยังไง

ถ้าย้อนความกลับไปถึงโพสที่แล้ว ก็คงพอจำกันได้นะคะว่า abstract argumentation framework (ขอเรียกย่อๆว่า AA) เนี่ย ประกอบไปด้วย เซตของ argument กับ attack relationship ที่บอกว่า argument ไหน attack argument ไหนบ้าง

ทีนี้พอเราจะเอาแนวคิดของ AA มาใช้ ก็เกิดคำถามขึ้นว่า แล้วโครงสร้างของ argument เป็นอะไรได้บ้างล่ะ ไม่เห็นมีรายละเอียดบอกเลย แล้ว attack relationship ล่ะ จะนิยามมันขึ้นมายังไง 
เจ้าตัว AA เนี่ยเป็นแนวคิดที่ generalize สุดๆแล้วเพื่อให้เป็นแนวทางสำหรับการทำ reasoning ก่อน ดังนั้นก็เลยไม่มีรายละเอียดให้ เวลาจะเอาไปใช้ คนใช้ก็ต้องไปออกแบบกันเอาเอง 

อย่างจะเห็นจากตัวอย่างในโพสที่แล้วเรื่องขนมเค้กหาย เรากำหนดให้แต่ละ argument เป็นแค่ statement ธรรมดาๆ และก็กำหนดค่า attack relationship ตรงๆ 

แต่ว่าในการทำ reasoning ที่เป็น logic-based เราก็จะมีการนำเอา logical deduction เข้ามาใช้ใช่ไหมคะ ซึ่งตรงนี้ ทำให้เราต้องกำหนดโครงสร้างให้กับ argument และ กำหนดรูปแบบการ attack ด้วย

ดังนั้น ในโพสนี้เรามาดูลูกหลาน หรือพูดง่ายๆคือ instance ของ AA กันบ้างค่ะ อันที่จริงมีงานหลายงานที่ถือได้ว่าเป็น instance ของ AA (และมีอีกหลายงานที่เอา AA ไปใช้ร่วมกับ approach อื่นๆ) แต่เราคงจะขอหยิบ instance of AA มาอธิบายแค่บางตัวนะคะ เอาเฉพาะตัวที่เราได้ศึกษาจริงๆจังๆเท่านั้น ซึ่งผู้อ่านท่านใดที่สนใจสามารถไปศึกษาเพิ่มเติมได้ค่ะ

งั้นวันนี้เรามาเริ่มที่ตัวแรกกันก่อน Assumption-Based Argumentation (ABA) framework  นะคะ ซึ่ง ABA มีแนวคิดที่เข้าใจง่าย แต่มีประสิทธิภาพยิ่งนักว่า "เราจะยอมรับข้อสมมติฐานใดๆได้ ตราบใดที่ยังไม่มีหลักฐานโต้แย้งข้อสมมติฐานนั้นๆ" 

จากประโยคนี้นี่แหละค่ะ เป็นตัวที่บ่งบอกว่าโครงสร้างของ ABA เป็นอย่างไร

นิยามของ ABA ก็มีดังนี้ค่ะ
ถ้าเรากำหนดให้ L เป็น language ใดๆ

  1. A เป็นซับเซตของ L ซึ่ง A เป็นเซตของ ข้อสมมติฐาน (A is a set of assumptions)
  2. R เป็น inference rules มีซึ่งลักษณะคือ  h ← b1,...,bn เมื่อ b แต่ละตัวสามารถที่จะเป็น ข้อเท็จจริงก็ได้ หรือจะเป็น assumption ก็ได้ค่ะ แต่ว่า h เนี่ยไม่สามารถเป็น assumption ได้ (คือเราไม่สามารถ derive ให้เป็นข้อสรุป assumption  ได้ค่ะ)
  3. (total) Mapping function T เป็นฟังก์ชันที่ทำการ map ค่าจาก เซตของ A ไปหา L ซึ่งค่าของ เรนจ์ที่เรา map ไปหาเนี่ย คือ ค่าที่เรากำหนดให้เป็นข้อโต้แย้ง(is a contrary of) ของ assumption นั้นๆนั่นเองค่ะ  ( T: A → L )

สมมติตัวอย่างนะคะ เอาจากตัวอย่างของโพสที่แล้วเรื่องเค้กหายเลยละกัน

ถ้าเรากำหนดให้ inference rules มีกฎดังนี้ (เราจะเขียนเป็นคำอธิบายก่อนนะคะ แล้วจะเขียนกฎในรูปแบบของ first order logic อีกที)

  • ถ้าเราไม่อนุญาตให้กินได้ แล้ว เด็กๆ ก็จะไม่กินเค้ก
  • ถ้า มีกระดาษเปื้อนเศษเค้กอยู่ในถังขยะ แล้ว ต้องมีคนกินเค้ก

และ ก็มีข้อเท็จจริงว่า
  • ทั้งบ้านเรา มีแค่ น้องเปรม ซึ่งเป็นหลานชาย
  • เรามีเค้กช็อคโกแลตวางอยู่ในตู้เย็น
  • เราไม่ได้อนุญาตให้หลานกินเค้ก
ซึ่งเราจะสามารถเขียนในรูปแบบของ inference rules ได้ดังนี้ค่ะ  (ขอเขียนโดยใช้ first order logic และจะเห็นว่า แต่ละ rule มีตัวแปรอยู่ ดังนั้น แต่ละ rule ก็สามารถที่จะมี instance ของตัวเองได้นะคะ)

R =

  • ~ Eat(X, Y) ← not_Get_permission(X), Cake(Y)
  • Eat(X,Y) ← Found_in_trash(Y), Nephew(X), Cake(Y)
  • Nephew( Prame ) ← 
  • Cake( Chocolate_Cake ) ←  
  • Found_in_trash( Chocolate_Cake ) ←  

ในที่นี้เรากำหนดให้ not_Get_permission เป็น assumption ค่ะ ซึ่งก็คือ เรามีสมมติฐานอยู่แล้วว่า เราไม่ได้อนุญาตให้ใครกินเค้กในตู้เย็น เพราะฉะนั้น A = {not_Get_permission(X)}

และ ข้อโต้แย้งของ not_Get_permission ก็คือ Get_permission  (ฟังก์ชัน mapping T(not_Get_permission(X) ) = Get_permission(X) )


ตอนนี้เราให้นิยามองค์ประกอบของ ABA ครบแล้วทั้งสามส่วนใช่ไหมคะ
ทวนนิดนึงว่า ABA เนี่ย เราจะสามารถ attack ได้เฉพาะตรง assumption เท่านั้น


ทีนี้เราก็จะมาทำการพิสูจน์กันล่ะว่า หลานได้กินเค้กไปหรือไม่ค่ะ ด้วยการหา semantic จาก argumentation framework based on ABA
อย่างที่บอกว่า ABA เนี่ยเป็น instance ของ AA ดังนั้น semantic ของ AA ก็ต้องถูกถ่ายทอดมาใช้ได้กับ ABA ทุกอย่างเลย

อย่างที่เราได้คุยกันไปแล้วในโพสที่แล้วว่า AA ประกอบด้วย arguments กับ attack relationship ใช่ไหมคะ  ก่อนอื่นเราก็มาสร้าง argument กันก่อนค่ะ

สำหรับการสร้าง argument ใน ABA นี้ ง่ายๆเลยเราก็มองเป็นรูปแบบของ ทรี ก็ได้ค่ะ
โดยเราจะให้ ข้อสรุป หรือ conclusion of argument เนี่ย เป็น root node  แล้วเราก็ทำการสร้างไล่ลงไปเรื่อยๆ ด้วยการเลือก inference rules หรือ assumption ที่สามารถให้ conclusion ของ node ที่เราต้องการได้ ซึ่งเราเรียกกระบวนการนี้ว่า backward deduction

ตัวอย่างเช่น เราจะทำการสร้าง argument ที่มี conclusion ว่า หลานกินเค้กไป (เพราะเราจะเริ่มพิสูจน์ข้อสันนิษฐานว่าหลานกินเค้กไปหรือไม่)  ซึ่งก็จะได้ argument A1 ตามรูปนะคะ

                                            Eat( Prame , Chocolate_Cake )
                                               ____________|___________
                                               |                       |                     |
 Found_in_trash( Chocolate_Cake )   Nephew( Prame )  Cake(Chocolate_Cake)
                      |                                                 |                    |
                     ◻                                               ◻                 ◻

จะเห็นว่าจากรูปทรี (พยายามมองให้เป็นทรีนะคะ ฮ่าๆๆ แบบว่าขี้เกียจไปวาดรูปข้างนอกมาแปะ ) ตรง leaf nodes จะเป็น ข้อเท็จจริงทั้งหมด  (สัญญลักษณ์ ◻ คือ tautology เป็นข้อเท็จจริงนะคะ)

ต่อมา เราจะลองสร้าง argument ที่มี conclusion ว่า หลานไม่ได้กินเค้กไป ก็จะได้ argument A2 ตามรูปค่ะ

                                            ~ Eat( Prame , Chocolate_Cake )
                                           _____________|___________                                           
                                           |                                               |
                  not_Get_permission( Prame)                    Cake(Chocolate_Cake)
                                                                                           |
                                                                                         ◻

ก็จะเห็นว่าจากรูปทรี ตรง leaf nodes เป็นข้อเท็จจริงก็ได้ หรือจะเป็น assumption ก็ได้ค่ะ

ซึ่งทั้งสองกรณีนี้จะถือว่าเป็น argument ที่สมบูรณ์ แต่ถ้าหากว่า leaf node ไม่ใช่ assumption หรือ ข้อเท็จจริงแล้ว จะไม่ถือว่าสร้าง argument เสร็จสมบูรณ์นะคะ

หลังจากสร้าง argument เสร็จแล้ว เรามาดู attack relationship กันบ้างค่ะ ซึ่งใน ABA เนี่ย เราจะมีรูปแบบการ attack เพียงอย่างเดียว คือ เราจะ attack ได้เฉพาะตรง  assumption เท่านั้น  ทีนี้จากตัวอย่างที่เรามีเนี่ย เรามี เซต assumption คือ A = {not_Get_permission(X)}
ซึ่ง จะเห็นว่าใน argument A2 มี assumption อยู่ ดังนั้น attack ที่จะเกิดได้คือเราสามารถ attack A2 ได้  ถ้าเรามีข้อโต้แย้ง ข้อสมมติฐานที่ว่า เราไม่ได้อนุญาตให้ใครกินเค้ก

ซึ่งเราไม่มีข้อโต้แย้งค่ะ (คือไม่มีข้อเท็จจริงที่ว่า น้องเปรมได้รับอนุญาตให้กินเค้ก)
ดังนั้น ก็เลยไม่มี attack เกิดขึ้น

เราก็จะได้ว่า argumentation framework based on ABA  เรียกว่า  AF = (AR, att) ซึ่ง AR = {A1, A2} และ att = empty set 

ดังนั้น ถ้าเราเอาไปหา semantic ของ AF ก็จะได้ว่า grounded extension = prefer extension = stable extension = { A1, A2} คือยอมรับทั้งสองข้อสรุป ว่า  น้องเปรมกินเค้กไป และ น้องเปรมไม่ได้กินเค้กไป


เพื่อให้เห็น attack relationship สมมติว่าเราเพิ่มข้อเท็จจริงไปอีกอย่างนึง ว่า

  • แม่อนุญาตให้น้องเปรมกินเค้กได้

เซต inference rules R ก็จะเพิ่มมาอีกหนึ่งกฎค่ะ ว่า

  • Get_permission( Prame ) ←

ดังนั้น เราก็จะสามารถสร้าง argument เพิ่มขึ้นมาอีกอันนึงคือ A3 ดังรูป

                                           Get_permission( Prame )
                                                              |
                                                             ◻


ทีนี้ เราก็จะเห็นว่า Get_permission( Prame ) เป็น ข้อโต้แย้ง ของ not_Get_permission( Prame)
ก็จะได้ว่า ฟังก์ชัน T ของเราคือ T(not_Get_permission(Prame)) = Get_permission(Prame)

ดังนั้น ก็จะได้ว่า A3 attacks A2 (คือเดิมที มีสมมติฐานว่า น้องเปรมไม่ได้รับอนุญาตให้กินเค้ก แต่ว่า มีข้อเท็จจริงมาแย้งว่า แม่ได้อนุญาตไปแล้ว )

ดังนั้น  AF ของเราก็จะเปลี่ยนเป็น  AF = (AR, att) ซึ่ง AR = {A1, A2,A3} และ att = {(A3,A2)}

พอเราไปหา semantic ของ AF ก็จะได้ว่า grounded extension = prefer extension = stable extension = { A1, A3} คือได้ข้อสรุป ว่า  น้องเปรมกินเค้กไป ค่ะ

สรุป โพสนี้นะคะ จะเห็นว่านี่เป็นการนำเอา argumentation มาใช้ในงาน reasoning ซึ่งไม่ยากเลยใช่ไหมคะ  สำหรับคนที่จะประยุกต์ใช้เฉยๆ ก็ไม่จำเป็นที่จะต้องเข้าใจ logic programming อย่างละเอียดมาก่อนก็ได้ เพราะถ้า represent ในแบบ ABA เราก็แค่กำหนด inference rule เท่านั้นเอง

ถ้าสังเกตดีๆ ก็จะเห็นว่า ABA มีลักษณะคล้ายคลึงกับ logic programming ค่ะ  เพราะตรง assumption จะคล้ายกับ negation as failure ใน logic programming  (แต่ว่าไม่ได้หมายความว่า มันคือ negation as finite failure นะคะ  เพราะ ABA ไม่ได้กำหนดว่าเป็น negation as finite failure หรือ negation as possibly infinite failure อะไรเลย มันคือ assumption ตราบใดที่หา ข้อโต้แย้งมาไม่ได้ ก็ต้องยอมรับมัน)

จริงๆแล้ว ก็มีหลายเปเปอร์เลยที่เอา ABA ไปใช้ ในงานด้านต่างๆ (ส่วนใหญ่อาจจะพบในงานด้านกฎหมายนะคะ)  สำหรับผู้อ่านท่านใดที่สนใจตัวทฤษฎี สามารถอ่านได้จากเปเปอร์ Assumption-Based Argumentation link  นะคะ

ตัวอย่างที่เรายกมาในบล็อกนี้ เราพยายามเลือกตัวอย่างง่ายๆ ไม่ซับซ้อน เพื่อที่จะได้เข้าใจภาพรวมก่อน ซึ่งเวลาที่เราเอาไป implement กับระบบจริงๆ ก็ย่อมที่จะซับซ้อนมากกว่า ตามโดเมนที่เราเลือก ตัว inference rules หรือ assumption เองก็อาจจะต้องออกแบบแตกต่างออกไป แต่ว่าไอเดียหลักก็ยังคงเหมือนกันค่ะ


สำหรับคนที่อยากจะเขียนโค้ดทดสอบ แบบง่ายๆก็ ใช้ prolog ได้เลยค่ะ เพราะว่า prolog เป็นเครื่องมือนึงที่สร้างจากแนวคิด logic programming  และในโพสแรกเราก็ได้เกริ่นไว้แล้ว  AA เองก็ prove ให้เห็นว่า มี semantics ที่ตรงกันกับ logic programming ดังนั้นก็ใช้ prolog ได้เลยค่ะ

ขอให้สนุกกับ argumentation นะคะ :)