ก่อนอื่นให้ฉันชมเชยคุณเกี่ยวกับไอคอน pw0n1e ที่ดีของคุณ
นี่เป็นคำถามที่ยากที่จะตอบส่วนใหญ่เป็นเพราะมีทั้ง miniKanren และ Prolog หลากหลายรูปแบบ miniKanren และ Prolog เป็นตระกูลภาษาจริงๆซึ่งทำให้ยากที่จะเปรียบเทียบคุณสมบัติของพวกเขาหรือแม้กระทั่งวิธีการใช้ในทางปฏิบัติ ด้วยเหตุนี้โปรดใช้ทุกสิ่งที่ฉันกำลังจะพูดด้วยความระมัดระวัง: ถ้าฉันบอกว่า Prolog ใช้การค้นหาเชิงลึกก่อนโปรดทราบว่าการใช้งาน Prolog จำนวนมากสนับสนุนกลยุทธ์การค้นหาอื่น ๆ และกลยุทธ์การค้นหาทางเลือกนั้นสามารถเข้ารหัสได้ที่เมตา - ระดับล่าม ถึงกระนั้น miniKanren และ Prolog ยังมีปรัชญาการออกแบบที่แตกต่างกันและทำการแลกเปลี่ยนที่แตกต่างกัน
Prolog เป็นหนึ่งในสองภาษาคลาสสิกสำหรับการเขียนโปรแกรมปัญญาประดิษฐ์เชิงสัญลักษณ์ (ภาษาคลาสสิกอื่น ๆ คือ Lisp) Prolog มีความเชี่ยวชาญในการนำระบบที่อิงกฎสัญลักษณ์มาใช้ซึ่งความรู้ที่เปิดเผยจะถูกเข้ารหัสด้วยตรรกะลำดับที่หนึ่ง ภาษาได้รับการปรับให้เหมาะสมสำหรับการแสดงออกและประสิทธิภาพสำหรับแอปพลิเคชันประเภทนี้โดยบางครั้งอาจต้องเสียค่าใช้จ่ายในเชิงตรรกะ ตัวอย่างเช่นโดยค่าเริ่มต้น Prolog จะไม่ใช้ "การตรวจสอบที่เกิดขึ้น" ในการรวม จากมุมมองทางคณิตศาสตร์ / ตรรกะการรวมเวอร์ชันนี้ไม่ถูกต้อง อย่างไรก็ตามการตรวจสอบที่เกิดขึ้นมีราคาแพงและในกรณีส่วนใหญ่การขาดการตรวจสอบที่เกิดขึ้นไม่ใช่ปัญหา นี่เป็นการตัดสินใจในการออกแบบเชิงปฏิบัติเช่นเดียวกับการใช้การค้นหาเชิงลึกก่อนและการใช้การตัดของ Prolog (!
) เพื่อควบคุมการย้อนกลับ ฉันแน่ใจว่าการตัดสินใจเหล่านี้จำเป็นอย่างยิ่งเมื่อทำงานบนฮาร์ดแวร์ของปี 1970 และวันนี้มีประโยชน์มากเมื่อต้องทำงานกับปัญหาใหญ่ ๆ และเมื่อต้องจัดการกับช่องว่างการค้นหาขนาดใหญ่
Prolog สนับสนุนคุณลักษณะ "extra-logical" หรือ "non-logical" มากมายรวมถึงการตัดassert
และการretract
ฉายภาพตัวแปรสำหรับการคำนวณโดยใช้is
และอื่น ๆ คุณสมบัติมากมายเหล่านี้ทำให้ง่ายต่อการแสดงขั้นตอนการควบคุมที่ซับซ้อนและจัดการกับฐานข้อมูลข้อเท็จจริงทั่วโลกของ Prolog คุณสมบัติที่น่าสนใจอย่างหนึ่งของ Prolog คือรหัส Prolog นั้นถูกเก็บไว้ในฐานข้อมูลทั่วโลกของข้อเท็จจริงและสามารถสอบถามได้ในขณะทำงาน สิ่งนี้ทำให้การเขียนเมตา - ล่ามที่ปรับเปลี่ยนพฤติกรรมของรหัส Prolog ภายใต้การตีความเป็นเรื่องเล็กน้อย ตัวอย่างเช่นเป็นไปได้ที่จะเข้ารหัสการค้นหาแบบกว้างเป็นอันดับแรกใน Prolog โดยใช้ meta-interpreter ที่เปลี่ยนลำดับการค้นหา นี่เป็นเทคนิคที่ทรงพลังอย่างยิ่งซึ่งไม่เป็นที่รู้จักกันดีนอกโลกของ Prolog 'The Art of Prolog' อธิบายเทคนิคนี้โดยละเอียด
ความพยายามอย่างมากในการปรับปรุงการใช้งาน Prolog ซึ่งส่วนใหญ่ใช้ Warren Abstract Machine (WAM) WAM ใช้แบบจำลองผลข้างเคียงซึ่งค่าต่างๆจะถูกกำหนดให้กับตัวแปรลอจิกโดยที่ผลข้างเคียงเหล่านี้จะถูกยกเลิกเมื่อทำการย้อนรอย คุณสามารถเพิ่มคุณสมบัติมากมายให้กับ Prolog ได้โดยการขยายคำแนะนำของ WAM ข้อเสียอย่างหนึ่งของแนวทางนี้คือเอกสารการใช้งาน Prolog อาจเป็นเรื่องยากที่จะอ่านหากไม่มีความเข้าใจอย่างชัดเจนเกี่ยวกับ WAM ในทางกลับกันผู้ใช้ Prolog มีแบบจำลองทั่วไปสำหรับการอภิปรายปัญหาการนำไปใช้งาน มีงานวิจัยจำนวนมากใน Prolog แบบคู่ขนานซึ่งจบลงที่อันดอร์รา Prolog ในปี 1990 อย่างน้อยก็มีแนวคิดเหล่านี้อยู่ใน Ciao Prolog (Ciao Prolog เต็มไปด้วยไอเดียที่น่าสนใจซึ่งหลายอย่างไปไกลกว่ามาตรฐาน Prolog)
Prolog มีไวยากรณ์สไตล์ "การจับคู่รูปแบบ" ตามการผสมผสานที่สวยงามซึ่งส่งผลให้โปรแกรมมีความกระชับมาก Prologers ชอบไวยากรณ์ของพวกเขาเช่นเดียวกับ Lispers ชอบการแสดงออกของพวกเขา Prolog ยังมีไลบรารีเพรดิเคตมาตรฐานขนาดใหญ่ เนื่องจากวิศวกรรมทั้งหมดที่ทำให้ WAM เป็นไปอย่างรวดเร็วจึงมีการใช้งาน Prolog ที่มีความสามารถและครบถ้วน ด้วยเหตุนี้ระบบฐานความรู้ขนาดใหญ่จำนวนมากจึงถูกเขียนขึ้นทั้งหมดใน Prolog
miniKanren ได้รับการออกแบบให้เป็นภาษาการเขียนโปรแกรมลอจิกขั้นต่ำโดยมีการใช้งานขนาดเล็กเข้าใจง่ายและสามารถแฮ็กได้ง่าย เดิม miniKanren ถูกฝังอยู่ใน Scheme และถูกย้ายไปยังโฮสต์ภาษาอื่น ๆ อีกหลายสิบภาษาในช่วงทศวรรษที่ผ่านมา การใช้งาน miniKanren ที่ได้รับความนิยมมากที่สุดคือ 'core.logic' ใน Clojure ซึ่งตอนนี้มีส่วนขยายคล้าย Prolog มากมายและการเพิ่มประสิทธิภาพจำนวนมาก เมื่อเร็ว ๆ นี้แกนหลักของการใช้งาน miniKanren ได้ถูกทำให้เรียบง่ายยิ่งขึ้นส่งผลให้เกิด "ไมโครเคอร์เนล" ขนาดเล็กที่เรียกว่า "microKanren" จากนั้นสามารถใช้ miniKanren ที่ด้านบนของแกน microKanren นี้ได้ การพอร์ต microKanren หรือ miniKanren เป็นภาษาโฮสต์ใหม่กลายเป็นแบบฝึกหัดมาตรฐานสำหรับโปรแกรมเมอร์ที่เรียนรู้ miniKanren ผลที่ตามมา,
การใช้งานมาตรฐานของ miniKanren และ microKanren ไม่มีการกลายพันธุ์หรือผลข้างเคียงอื่น ๆ โดยมีข้อยกเว้นเพียงประการเดียว: miniKanren บางเวอร์ชันใช้ความเท่าเทียมกันของตัวชี้สำหรับการเปรียบเทียบตัวแปรลอจิก ฉันคิดว่านี่เป็น "ผลที่ไม่เป็นอันตราย" แม้ว่าการใช้งานจำนวนมากจะหลีกเลี่ยงผลกระทบนี้ด้วยการส่งตัวนับผ่านการใช้งาน นอกจากนี้ยังไม่มีฐานข้อมูลข้อเท็จจริงทั่วโลก ปรัชญาการใช้งานของ miniKanren ได้รับแรงบันดาลใจจากการเขียนโปรแกรมเชิงฟังก์ชัน: ควรหลีกเลี่ยงการกลายพันธุ์และผลกระทบและโครงสร้างภาษาทั้งหมดควรเคารพขอบเขตคำศัพท์ หากคุณดูการใช้งานอย่างรอบคอบคุณอาจเห็น monads สองสามตัว การใช้งานการค้นหาจะขึ้นอยู่กับการรวมและจัดการสตรีมขี้เกียจอีกครั้งโดยไม่ต้องใช้การกลายพันธุ์ ตัวเลือกการใช้งานเหล่านี้นำไปสู่การแลกเปลี่ยนที่แตกต่างจากใน Prolog ใน Prolog การค้นหาตัวแปรเป็นเวลาที่คงที่ แต่การย้อนรอยต้องมีการยกเลิกผลข้างเคียง ในการค้นหาตัวแปร miniKanren มีราคาแพงกว่า แต่การติดตามย้อนกลับเป็น "ฟรี" ในความเป็นจริงแล้ว miniKanren ไม่มีการย้อนกลับเนื่องจากวิธีการจัดการสตรีม
สิ่งที่น่าสนใจอย่างหนึ่งของการใช้งาน miniKanren คือโค้ดนั้นปลอดภัยโดยเนื้อแท้และ --- อย่างน้อยก็ในทางทฤษฎี --- ขนานกันเล็กน้อย แน่นอนว่าการขนานรหัสโดยไม่ทำให้ช้าลงนั้นไม่ใช่เรื่องเล็กน้อยเนื่องจากแต่ละเธรดหรือกระบวนการจะต้องได้รับงานเพียงพอที่จะชดเชยค่าใช้จ่ายของการขนาน อย่างไรก็ตามนี่เป็นส่วนหนึ่งของการใช้งาน miniKanren ที่ฉันหวังว่าจะได้รับความสนใจและการทดลองมากขึ้น
miniKanren ใช้การตรวจสอบที่เกิดขึ้นสำหรับการรวมและใช้การค้นหาแบบสอดแทรกแบบสมบูรณ์แทนการค้นหาแบบเจาะลึกก่อน การค้นหาแบบสอดแทรกใช้หน่วยความจำมากกว่าการค้นหาแบบเจาะลึกก่อน แต่สามารถค้นหาคำตอบได้ในบางกรณีที่การค้นหาในเชิงลึกจะแตกต่าง / วนซ้ำตลอดไป miniKanren ไม่สนับสนุนพิเศษตรรกะประกอบ --- ไม่กี่conda
, condu
และproject
ยกตัวอย่างเช่น conda
และcondu
สามารถใช้เพื่อจำลองการตัดของ Prolog และproject
สามารถใช้เพื่อรับค่าที่เกี่ยวข้องกับตัวแปรลอจิก
การปรากฏตัวของconda
, condu
และproject
--- และความสามารถในการปรับเปลี่ยนกลยุทธ์การค้นหาได้อย่างง่ายดาย --- ช่วยให้โปรแกรมเมอร์ใช้ miniKanren เป็นภาษาที่คล้ายกับ Prolog ในตัว โดยเฉพาะอย่างยิ่งสำหรับผู้ใช้ 'core.logic' ของ Clojure ซึ่งมีส่วนขยายคล้าย Prolog มากมาย การใช้ miniKanren แบบ "เชิงปฏิบัติ" นี้ดูเหมือนจะเป็นการใช้งานส่วนใหญ่ของ miniKanren ในอุตสาหกรรม โปรแกรมเมอร์ที่ต้องการเพิ่มระบบการให้เหตุผลตามความรู้ลงในแอปพลิเคชันที่มีอยู่ซึ่งเขียนด้วย Clojure หรือ Python หรือ JavaScript มักไม่สนใจที่จะเขียนแอปพลิเคชันใหม่ทั้งหมดใน Prolog การฝังภาษาการเขียนโปรแกรมลอจิกขนาดเล็กใน Clojure หรือ Python นั้นน่าสนใจกว่ามาก การติดตั้ง Prolog แบบฝังจะใช้ได้ดีสำหรับจุดประสงค์นี้ซึ่งน่าจะเป็นไปได้
นอกเหนือจากการใช้ miniKanren เป็นภาษาการเขียนโปรแกรมลอจิกฝังตัวในทางปฏิบัติที่คล้ายคลึงกับ Prolog แล้ว miniKanren ยังถูกใช้เพื่อการวิจัยในการเขียนโปรแกรมเชิงสัมพันธ์ นั่นคือในการเขียนโปรแกรมที่มีพฤติกรรมเป็นความสัมพันธ์ทางคณิตศาสตร์มากกว่าฟังก์ชันทางคณิตศาสตร์ ยกตัวอย่างเช่นในโครงการที่append
ฟังก์ชั่นสามารถผนวกสองรายการกลับรายการใหม่: การเรียกใช้ฟังก์ชันส่งกลับรายการ(append '(a b c) '(d e))
(a b c d e)
อย่างไรก็ตามเราสามารถถือว่าappend
เป็นความสัมพันธ์สามสถานที่แทนที่จะเป็นฟังก์ชันสองอาร์กิวเมนต์ โทร(appendo '(a b c) '(d e) Z)
จากนั้นก็จะเชื่อมโยงตัวแปรตรรกะกับรายการZ
(a b c d e)
แน่นอนว่าสิ่งที่น่าสนใจยิ่งขึ้นเมื่อเราวางตัวแปรลอจิกในตำแหน่งอื่น ๆ การโทร(appendo X '(d e) '(a b c d e))
เชื่อมโยงX
กับ(a b c)
ในขณะที่โทร(appendo X Y '(a b c d e))
เพื่อนร่วมงานX
และกับคู่ของรายการที่เมื่อผนวกจะเท่ากับY
(a b c d e)
ตัวอย่างเช่นX
= (a b)
และY
= (c d e)
คือคู่ค่าดังกล่าว นอกจากนี้เรายังสามารถเขียน(appendo X Y Z)
ซึ่งจะผลิตอเนกประสงค์หลายอย่างมากมายของรายการX
, Y
และZ
เช่นที่ผนวกX
การผลิตY
Z
เวอร์ชันเชิงสัมพันธ์นี้append
สามารถแสดงใน Prolog ได้อย่างง่ายดายและมีการแสดงในแบบฝึกหัด Prolog มากมาย ในทางปฏิบัติโปรแกรม Prolog ที่ซับซ้อนมากขึ้นมักจะใช้คุณสมบัติเชิงตรรกะพิเศษอย่างน้อยสองสามอย่างเช่นการตัดซึ่งขัดขวางความสามารถในการปฏิบัติต่อโปรแกรมที่เป็นผลลัพธ์เป็นความสัมพันธ์ ในทางตรงกันข้าม miniKanren ได้รับการออกแบบมาอย่างชัดเจนเพื่อรองรับรูปแบบของการเขียนโปรแกรมเชิงสัมพันธ์นี้ รุ่นอื่น ๆ ที่ผ่านมาของ miniKanren มีการสนับสนุนการแก้ข้อ จำกัด สัญลักษณ์ ( symbolo
, numbero
,absento
, ข้อ จำกัด ด้านความเป็นโรค, การเขียนโปรแกรมลอจิกเล็กน้อย) เพื่อให้ง่ายต่อการเขียนโปรแกรมที่ไม่สำคัญเป็นความสัมพันธ์ ในทางปฏิบัติฉันไม่เคยใช้คุณสมบัติพิเศษใด ๆ ของ miniKanren และฉันเขียนโปรแกรม miniKanren ทั้งหมดเป็นความสัมพันธ์ โปรแกรมเชิงสัมพันธ์ที่น่าสนใจที่สุดคือล่ามเชิงสัมพันธ์สำหรับชุดย่อยของ Scheme ล่ามเหล่านี้มีความสามารถที่น่าสนใจมากมายเช่นการสร้างโปรแกรม Scheme หนึ่งล้านโปรแกรมที่ประเมินตามรายการ(I love you)
หรือสร้าง quines เล็กน้อย (โปรแกรมที่ประเมินตัวเอง)
miniKanren ทำการแลกเปลี่ยนเพื่อเปิดใช้งานรูปแบบการเขียนโปรแกรมเชิงสัมพันธ์นี้ซึ่งแตกต่างจากที่ Prolog ทำอย่างมาก เมื่อเวลาผ่านไป miniKanren ได้เพิ่มข้อ จำกัด เชิงสัญลักษณ์มากขึ้นกลายเป็นภาษาการเขียนโปรแกรมลอจิกข้อ จำกัด เชิงสัญลักษณ์ ในหลายกรณีเหล่านี้ จำกัด สัญลักษณ์ทำให้การปฏิบัติเพื่อหลีกเลี่ยงการใช้ประกอบการพิเศษตรรกะเหมือนและcondu
project
ในกรณีอื่น ๆ ข้อ จำกัด เชิงสัญลักษณ์เหล่านี้ไม่เพียงพอ การสนับสนุนที่ดีขึ้นสำหรับข้อ จำกัด เชิงสัญลักษณ์เป็นส่วนหนึ่งของการวิจัยของ miniKanren พร้อมกับคำถามที่กว้างขึ้นเกี่ยวกับวิธีการเขียนโปรแกรมที่ใหญ่ขึ้นและซับซ้อนขึ้นเป็นความสัมพันธ์
กล่าวโดยย่อทั้ง miniKanren และ Prolog มีคุณสมบัติการใช้งานและการใช้งานที่น่าสนใจและฉันคิดว่ามันคุ้มค่าที่จะเรียนรู้แนวคิดจากทั้งสองภาษา มีภาษาโปรแกรมตรรกะอื่น ๆ ที่น่าสนใจเช่นกันเช่น Mercury, Curry และGödelซึ่งแต่ละภาษามีการเขียนโปรแกรมตรรกะของตัวเอง
ฉันจะปิดท้ายด้วยแหล่งข้อมูล miniKanren บางส่วน:
เว็บไซต์หลักของ miniKanren:
http://minikanren.org/
บทสัมภาษณ์ที่ฉันให้เกี่ยวกับการเขียนโปรแกรมเชิงสัมพันธ์และ miniKanren รวมถึงการเปรียบเทียบกับ Prolog:
http://www.infoq.com/interviews/byrd-relational-programming-minikanren
ไชโย
--จะ