เรารู้อะไรเกี่ยวกับโปรแกรมที่ถูกต้องที่พิสูจน์ได้?


37

ความซับซ้อนที่เพิ่มขึ้นของโปรแกรมคอมพิวเตอร์และคอมพิวเตอร์ที่มีความสำคัญยิ่งขึ้นเรื่อย ๆ ทำให้เราสงสัยว่าทำไมเรายังไม่ใช้ภาษาโปรแกรมร่วมกันซึ่งคุณต้องแสดงหลักฐานอย่างเป็นทางการว่ารหัสของคุณทำงานอย่างถูกต้อง

ฉันเชื่อว่าคำว่า 'รับรอง compiler' (ฉันพบที่นี่ ): คอมไพเลอร์รวบรวมภาษาการเขียนโปรแกรมที่ไม่เพียง แต่ต้องเขียนรหัส แต่ยังระบุคุณสมบัติของรหัสและพิสูจน์ว่ารหัสปฏิบัติตาม สเปค (หรือใช้โปรแกรมพิสูจน์อัตโนมัติ)

ขณะค้นหาอินเทอร์เน็ตฉันพบโครงการที่ใช้ภาษาการเขียนโปรแกรมง่าย ๆ หรือโครงการที่ล้มเหลวซึ่งพยายามปรับภาษาการเขียนโปรแกรมที่ทันสมัย สิ่งนี้ทำให้ฉันคำถามของฉัน:

มีคอมไพเลอร์ที่ผ่านการรับรองใด ๆ ที่ใช้ภาษาการเขียนโปรแกรมแบบเต็มเป่าหรือเป็นไปไม่ได้ในทางทฤษฎีหรือเป็นไปไม่ได้?

นอกจากนี้ฉันยังไม่เห็นคลาสความซับซ้อนใด ๆ ที่เกี่ยวข้องกับโปรแกรมที่พิสูจน์ได้เช่น 'คลาสของทุกภาษาที่ decidable โดยเครื่องทัวริงซึ่งมีการพิสูจน์ว่าเครื่องทัวริงนี้หยุดทำงาน' ซึ่งฉันจะเรียกว่าเป็นอะนาล็อกชุดของภาษาแบบเรียกซ้ำProvableRR

ฉันสามารถเห็นข้อดีของการเรียนคลาสที่ซับซ้อนเช่น: สำหรับProvableRปัญหา Halting นั้นสามารถตัดสินใจได้ (ฉันยังคาดเดาProvableREกำหนดไว้ในวิธีที่ชัดเจนว่าจะเป็นคลาสที่ใหญ่ที่สุดของภาษาที่มันสามารถถอดรหัสได้) นอกจากนี้ฉันสงสัยว่าเราจะแยกแยะโปรแกรมที่มีประโยชน์จริง ๆ : ใครจะใช้โปรแกรมเมื่อคุณไม่สามารถพิสูจน์ได้ว่ายุติ

ดังนั้นคำถามที่สองของฉันคือ:

เรารู้อะไรเกี่ยวกับคลาสความซับซ้อนที่ต้องการภาษาที่มีภาษาของพวกเขาเพื่อให้มีคุณสมบัติบางอย่าง?


1
คอมไพเลอร์สามารถระบุการพิสูจน์ความยาวที่เป็นไปได้ทั้งหมดโดยปล่อยให้ฉันไปจาก 1 ถึงไม่สิ้นสุดจนกว่าจะพบหลักฐานว่าโปรแกรมหยุดทำงาน หากเราต้องการให้อินพุตสำหรับคอมไพเลอร์หยุดอย่างชั่วคราวแล้วคอมไพเลอร์จะพบหลักฐานนั้นเสมอ เนื่องจากปัญหาการหยุดชะงักไม่สามารถตัดสินใจได้เราจะต้องสรุปว่ามีโปรแกรมที่หยุด แต่ไม่มีข้อพิสูจน์สำหรับสิ่งนี้ จุดสำคัญคือโปรแกรมไม่สามารถตรวจสอบว่ามีการพิสูจน์อยู่หรือไม่ไม่ใช่โปรแกรมนั้นไม่สามารถหาหลักฐานได้หากมีอยู่
อเล็กซ์สิบ Brink

3
ฉันคิดว่าคุณควรแยกพวกเขาออก พวกเขาเป็นคำถามที่แตกต่างกับคำตอบที่แตกต่างกัน
Mark Reitblatt

4
ในคำถามแรกกระดาษที่มีอิทธิพลคือ "กระบวนการทางสังคมและการพิสูจน์ทฤษฎีบทและโปรแกรม", portal.acm.org/citation.cfm?id=359106
Colin McQuillan

1
การตรวจสอบโปรแกรมไม่สามารถตัดสินใจได้ ดังนั้นปัญหาหนึ่งคือการพูดในสิ่งที่ถือเป็นทางออกที่ดี ดูcstheory.stackexchange.com/questions/4016/…
Radu GRIGore

2
@ โคลลิน: กระดาษแผ่นนี้มีค่าสำหรับการอ่านเพื่อวิเคราะห์หลักฐาน แต่การคาดการณ์ของมันได้รับการปลอมแปลง วันนี้เราได้แก้ไขคอมไพเลอร์เมล็ดระบบปฏิบัติการตัวรวบรวมขยะและฐานข้อมูลซึ่งทั้งหมดนี้คาดว่าจะเป็นไปไม่ได้ เคล็ดลับในการหลบเลี่ยงการวิจารณ์ของพวกเขาคือการหลีกเลี่ยงการตรวจสอบความถูกต้องของมนุษย์ในรายละเอียดระดับต่ำของการพิสูจน์อย่างเป็นทางการ แต่จะใช้การตรวจสอบเครื่องของการพิสูจน์และใช้มนุษย์เพื่อตรวจสอบการตรวจสอบหลักฐาน ทฤษฎีการอ้างอิงถึงทฤษฎีการพิมพ์ของนัมคือที่ซึ่งสถานะของศิลปะอยู่ซึ่งทำให้โปรแกรมที่จำเป็นต้องมีการผูกไว้ตั้งแต่ทฤษฎีประเภททำงานได้
Neel Krishnaswami

คำตอบ:


28

"การรับรองคอมไพเลอร์" มักจะหมายถึงบางสิ่งที่แตกต่างออกไปเล็กน้อยนั่นหมายความว่าคุณมีคอมไพเลอร์ซึ่งสามารถพิสูจน์ได้ว่ารหัสเครื่องที่ปล่อยออกมานั้นใช้ความหมายระดับสูงอย่างถูกต้อง นั่นคือนี่เป็นการพิสูจน์ว่าไม่มีข้อบกพร่องของคอมไพเลอร์ โปรแกรมที่ผู้ใช้ให้กับคอมไพเลอร์อาจยังคงผิดพลาดได้ แต่คอมไพเลอร์จะสร้างเวอร์ชันเครื่องที่ถูกต้องของโปรแกรมที่ผิด เรื่องราวความสำเร็จที่ยิ่งใหญ่ที่สุดในสายเหล่านี้คือคอมไพเลอร์ที่ผ่านการตรวจสอบ CompCertซึ่งเป็นคอมไพเลอร์สำหรับชุดย่อยขนาดใหญ่ของ C

คอมไพเลอร์คอมไพเลอร์ตัวเองเป็นโปรแกรมที่มีการพิสูจน์ความถูกต้อง (ทำใน Coq) ซึ่งรับประกันได้ว่าถ้ามันสร้างรหัสสำหรับโปรแกรมมันจะถูกต้อง (เกี่ยวกับความหมายของการดำเนินงานของการประกอบ & C ที่นักออกแบบ CompCert ใช้) ความพยายามในการตรวจสอบเครื่องจักรสิ่งเหล่านี้ค่อนข้างใหญ่ โดยทั่วไปแล้วการพิสูจน์ความถูกต้องจะอยู่ที่ขนาด 1x ถึง 100 เท่าของโปรแกรมที่คุณกำลังตรวจสอบ การเขียนโปรแกรมและหลักฐานที่ตรวจสอบด้วยเครื่องเป็นทักษะใหม่ที่คุณต้องเรียนรู้ไม่ใช่คณิตศาสตร์หรือการเขียนโปรแกรมตามปกติแม้ว่ามันจะขึ้นอยู่กับความสามารถในการทำทั้งสองอย่าง รู้สึกเหมือนคุณเริ่มต้นจากศูนย์เหมือนเป็นโปรแกรมเมอร์มือใหม่อีกครั้ง

ไม่มีสิ่งกีดขวางทางทฤษฎีพิเศษสำหรับเรื่องนี้แม้ว่า สิ่งเดียวที่อยู่ในบรรทัดเหล่านี้คือทฤษฎีบท Blum Sizeซึ่งสำหรับภาษาใด ๆ ที่ทุกโปรแกรมมีผลรวมคุณสามารถค้นหาโปรแกรมในภาษาแบบเรียกซ้ำโดยทั่วไปซึ่งจะมีขนาดใหญ่ขึ้นอย่างน้อยเมื่อชี้แจงในภาษาทั้งหมด วิธีที่จะเข้าใจผลลัพธ์นี้คือการเข้ารหัสภาษาทั้งหมดไม่เพียง แต่เป็นโปรแกรม แต่ยังเป็นหลักฐานการยกเลิก ดังนั้นคุณสามารถมีโปรแกรมสั้น ๆ พร้อมหลักฐานการเลิกจ้างที่ยาวนาน อย่างไรก็ตามสิ่งนี้ไม่สำคัญในทางปฏิบัติเนื่องจากเราจะเขียนโปรแกรมที่มีหลักฐานการเลิกจ้างที่จัดการได้เท่านั้น

แก้ไข: Dai Le ขอความละเอียดบางส่วนของจุดสุดท้าย

นี่คือการอ้างสิทธิ์ที่ใช้ประโยชน์ได้ส่วนใหญ่ขึ้นอยู่กับความจริงที่ว่าถ้าคุณสามารถเข้าใจว่าทำไมโปรแกรมถึงทำงานได้ก็ไม่น่าเป็นไปได้ว่าเหตุผลนั้นมีบางหน้ายาวหลายล้านอันที่คงที่ (ค่าคงที่ที่ยาวที่สุดที่ฉันเคยใช้มีเพียงไม่กี่หน้าและเด็กพวกเขาทำให้ผู้ตรวจสอบบ่นด้วยเช่นกันเนื่องจากค่าคงที่คือเหตุผลที่โปรแกรมใช้การบรรยายทั้งหมดที่ช่วยให้ผู้คนเข้าใจได้)

แต่ก็มีเหตุผลทางทฤษฎีด้วยเช่นกัน โดยพื้นฐานแล้วเราไม่รู้วิธีการประดิษฐ์โปรแกรมอย่างเป็นระบบซึ่งมีข้อพิสูจน์ความถูกต้องที่ยาวมาก วิธีการหลักคือ (1) ใช้ตรรกะที่คุณพิสูจน์ความถูกต้อง (2) ค้นหาคุณสมบัติที่ไม่สามารถแสดงออกได้โดยตรงในตรรกะนั้น (พิสูจน์ความสอดคล้องกันเป็นแหล่งทั่วไป) และ (3) ค้นหาโปรแกรมที่มี การพิสูจน์ความถูกต้องขึ้นอยู่กับครอบครัวของผลกระทบที่ชัดเจนของคุณสมบัติที่อธิบายไม่ได้ เนื่องจาก (2) ไม่สามารถอธิบายได้ซึ่งหมายความว่าการพิสูจน์ของผลลัพธ์ที่ชัดเจนแต่ละครั้งจะต้องทำอย่างอิสระซึ่งช่วยให้คุณขยายขนาดของการพิสูจน์ความถูกต้องได้ ตัวอย่างง่ายๆให้สังเกตว่าในตรรกะลำดับแรกที่มีความสัมพันธ์กับผู้ปกครองคุณไม่สามารถแสดงความสัมพันธ์ของบรรพบุรุษได้k kkk) เป็นแสดงออกสำหรับแต่ละคงที่kดังนั้นโดยการให้โปรแกรมที่ใช้สมบัติบางอย่างของบรรพบุรุษถึงความลึก (พูด 100) คุณสามารถบังคับพิสูจน์ความถูกต้องใน FOL เพื่อให้มีการพิสูจน์คุณสมบัติเหล่านั้นร้อยครั้งk

ความซับซ้อนในเรื่องนี้เรียกว่า "คณิตศาสตร์ย้อนกลับ" และเป็นการศึกษาที่จำเป็นต้องพิสูจน์สัจพจน์สัจพจน์ ฉันไม่รู้เรื่องนี้มากนัก แต่ถ้าคุณโพสต์คำถามลงในใบสมัครกับ CS และฉันแน่ใจว่าอย่างน้อย Timothy Chow และคนอื่น ๆ อีกหลายคนอาจจะบอกสิ่งที่น่าสนใจกับคุณได้


1
คุณช่วยอธิบายเพิ่มเติมในประเด็นนี้ได้ไหมว่า "เราจะเขียนโปรแกรมที่มีการพิสูจน์การเลิกจ้างที่จัดการได้" อีกเล็กน้อย?
Dai Le

ขอบคุณสำหรับคำตอบที่อัพเดต! คำตอบของคุณเปิดมุมมองของฉันจริงๆ ที่จริงแล้วฉันเองก็ใช้งานได้กับ "reverse math" แต่ฉันไม่ได้ตระหนักถึงการเชื่อมต่อที่คุณกล่าวถึง ขอบคุณอีกครั้ง!
Dai Le

1
ประเด็นในการแก้ไขของคุณนั้นเกี่ยวข้องกับความจริงที่ว่าเรามีผู้สมัครไม่มากนักสำหรับการพูดซ้ำซากที่ต้องใช้การพิสูจน์นานในระบบการพิสูจน์ตามธรรมชาติ (เช่น, พูด, Frege) ส่วนหนึ่งของเหตุผลสำหรับเรื่องนี้ก็คือวิธีเดียวที่เรารู้ว่าการออกเสียงซ้ำซากนั้นมีความสำคัญในตอนแรกเพราะเรามีข้อพิสูจน์ในใจซึ่งไม่จำเป็นต้องนานนัก!
Joshua Grochow

22

ฉันคิดว่าคำตอบสำหรับคำถามแรกคือโดยทั่วไปแล้วมันใช้งานได้กับเครื่องมือปัจจุบันมากเกินไป เพื่อให้ได้ความรู้สึกฉันแนะนำให้พยายามพิสูจน์ความถูกต้องของ Bubble Sort ใน Coq (หรือหากคุณต้องการความท้าทายมากกว่านี้ให้ใช้ Quick Sort) ฉันไม่คิดว่ามันสมเหตุสมผลที่จะคาดหวังว่าโปรแกรมเมอร์เขียนโปรแกรมที่ตรวจสอบแล้วตราบใดที่การพิสูจน์ความถูกต้องของอัลกอริธึมพื้นฐานนั้นยากและใช้เวลานาน

คำถามนี้คล้ายกับการถามว่าทำไมนักคณิตศาสตร์ไม่เขียนหลักฐานพิสูจน์ที่เป็นทางการที่สามารถตรวจสอบได้โดยเครื่องมือตรวจสอบหลักฐาน การเขียนโปรแกรมที่มีการพิสูจน์ความถูกต้องอย่างเป็นทางการหมายถึงการพิสูจน์ทฤษฎีบททางคณิตศาสตร์เกี่ยวกับรหัสที่เขียนและการตอบคำถามนั้นก็ใช้กับคำถามของคุณเช่นกัน

นี่ไม่ได้หมายความว่ายังไม่ประสบความสำเร็จในการตรวจสอบกรณี ฉันรู้ว่ามีกลุ่มที่จะพิสูจน์ความถูกต้องของระบบเช่นไฮเปอร์ไวเซอร์ไมโครซอฟท์ กรณีที่เกี่ยวข้องคือไมโครซอฟท์ได้รับการยืนยัน C คอมไพเลอร์ แต่โดยทั่วไปเครื่องมือในปัจจุบันต้องการการพัฒนาจำนวนมาก (รวมถึงแง่มุมของ SE และ HCI) ก่อนที่จะเป็นประโยชน์สำหรับโปรแกรมเมอร์ทั่วไป (และนักคณิตศาสตร์)

ตามวรรคสุดท้ายของคำตอบของ Neelเกี่ยวกับการเพิ่มขนาดโปรแกรมสำหรับภาษาที่มีฟังก์ชั่นรวมเท่านั้นจริง ๆ แล้วมันง่ายที่จะพิสูจน์ได้มากขึ้น (ถ้าฉันเข้าใจถูกต้อง) มีเหตุผลที่จะคาดหวังว่าไวยากรณ์ของภาษาโปรแกรมใด ๆ ที่จะถูก ce และชุดของฟังก์ชั่นที่คำนวณได้ทั้งหมดไม่ได้เป็น ce ดังนั้นสำหรับภาษาการเขียนโปรแกรมใด ๆ ที่โปรแกรมทั้งหมดมีผลรวมมีฟังก์ชั่นที่คำนวณได้ทั้งหมด ขนาดใดก็ได้) ในภาษานั้น


สำหรับคำถามที่สองฉันตอบคำถามคล้าย ๆ กันในบล็อกของ Scott เมื่อไม่นานมานี้ โดยพื้นฐานแล้วหากคลาสความซับซ้อนมีลักษณะที่ดีและสามารถคำนวณได้ (เช่นมันคือ ce) เราสามารถพิสูจน์ได้ว่าการแทนปัญหาในคลาสความซับซ้อนนั้นพิสูจน์ได้ในทฤษฎีที่อ่อนแอมากซึ่งสอดคล้องกับคลาสที่ซับซ้อน แนวคิดพื้นฐานคือฟังก์ชั่นทั้งหมดที่พิสูจน์ได้ของทฤษฎีประกอบด้วยฟังก์ชันและปัญหาซึ่งเป็น - สมบูรณ์สำหรับคลาสความซับซ้อนดังนั้นจึงมีปัญหาทั้งหมดในคลาสความซับซ้อนและสามารถพิสูจน์ผลรวมของโปรแกรมเหล่านั้น . ความสัมพันธ์ระหว่างการพิสูจน์และทฤษฎีความซับซ้อนนั้นมีการศึกษาในความซับซ้อนในการพิสูจน์ดูหนังสือเล่มล่าสุดของ SA Cook และ P. Nguyen " A C 0AC0AC0ฐานรากเชิงตรรกะของการพิสูจน์ความซับซ้อน "ถ้าคุณสนใจ ( ฉบับร่างจากปี 2008 มีให้บริการแล้ว) ดังนั้นคำตอบพื้นฐานคือสำหรับหลาย ๆ คลาส" Provably C = C "

สิ่งนี้ไม่เป็นความจริงโดยทั่วไปเนื่องจากมีคลาสความซับซ้อนทางความหมายซึ่งไม่มีลักษณะทางไวยากรณ์เช่นฟังก์ชันที่คำนวณได้ทั้งหมด ถ้าคุณเรียกซ้ำ recursive ฟังก์ชั่น recursive รวมแล้วทั้งสองจะไม่เท่ากันและชุดของฟังก์ชั่นคำนวณซึ่งพิสูจน์ได้โดยรวมในทฤษฎีที่ดีในการศึกษาทฤษฎีพิสูจน์วรรณกรรมและเรียกว่าฟังก์ชั่นรวมของทฤษฎี ตัวอย่างเช่น: ฟังก์ชันทั้งหมดที่พิสูจน์ได้ของคือ -recursive function (หรือฟังก์ชันที่เทียบเท่าในระบบ Godel ของ ), ฟังก์ชันทั้งหมดที่พิสูจน์ได้ของเป็นฟังก์ชันในระบบของ Girard , ฟังก์ชันทั้งหมดที่พิสูจน์ได้ของϵ 0 T P A 2 F ฉันΣ 1PAϵ0TPA2FIΣ1 เป็นฟังก์ชันแบบเรียกซ้ำแบบดั้งเดิม, ...

แต่ดูเหมือนจะไม่สำหรับฉันที่นี่มีความหมายอย่างมากในบริบทการตรวจสอบโปรแกรมเนื่องจากยังมีโปรแกรมที่ขยายการคำนวณฟังก์ชั่นเดียวกัน แต่เราไม่สามารถพิสูจน์ได้ว่าทั้งสองโปรแกรมกำลังคำนวณฟังก์ชั่นเดียวกัน จงใจ (นี่คล้ายกับ Morning Star และ Evening Star) นอกจากนี้ยังง่ายต่อการปรับเปลี่ยนโปรแกรมทั้งหมดที่ได้รับการพิสูจน์เพื่อให้ได้โปรแกรมที่ทฤษฎีไม่สามารถพิสูจน์ผลรวมได้


ฉันคิดว่าคำถามสองข้อนั้นเกี่ยวข้องกัน วัตถุประสงค์คือเพื่อรับโปรแกรมที่ผ่านการตรวจสอบ โปรแกรมที่ผ่านการตรวจสอบหมายความว่าโปรแกรมนั้นตรงตามคำอธิบายซึ่งเป็นข้อความทางคณิตศาสตร์ วิธีหนึ่งคือการเขียนโปรแกรมในภาษาการเขียนโปรแกรมแล้วพิสูจน์คุณสมบัติของมันเหมือนมันเป็นไปตามคำอธิบายซึ่งเป็นวิธีปฏิบัติทั่วไป อีกทางเลือกหนึ่งคือพยายามพิสูจน์คำแถลงทางคณิตศาสตร์ที่อธิบายถึงปัญหาโดยใช้วิธีการที่ถูก จำกัด แล้วแยกโปรแกรมที่ผ่านการตรวจสอบจากมัน ตัวอย่างเช่นถ้าเราพิสูจน์ในทฤษฎีที่สอดคล้องกับว่าสำหรับจำนวนใดก็ตามมีลำดับของจำนวนเฉพาะที่ผลิตภัณฑ์ของพวกเขาเท่ากับจากนั้นเราสามารถดึงn n PPnnPอัลกอริทึมสำหรับการแยกตัวประกอบจากการพิสูจน์ (นอกจากนี้ยังมีนักวิจัยที่พยายามทำให้แนวทางแรกโดยอัตโนมัติให้มากที่สุดเท่าที่จะทำได้ แต่การตรวจสอบคุณสมบัติที่ไม่น่าสนใจของโปรแกรมนั้นยากที่จะคำนวณและไม่สามารถตรวจสอบได้อย่างสมบูรณ์โดยไม่มีข้อผิดพลาดเชิงบวกและเชิงลบ)


3
คำตอบที่ดี! คุณพูดถึงวิธีหนึ่งคือการแยกโปรแกรมออกจากบทพิสูจน์ซึ่งเป็นสิ่งที่เราสามารถทำได้โดยอัตโนมัติใน Coq พื้นที่ที่เกี่ยวข้องคือการทำเหมืองพิสูจน์ซึ่งผู้คน (ทำงานโดยปกติในตรรกะทางคณิตศาสตร์) พยายามที่จะดึงข้อมูลจากการพิสูจน์ที่กำหนด ตัวอย่างเช่นเป็นไปได้ในบางกรณีที่จะ (โดยอัตโนมัติ) ค้นหาข้อพิสูจน์สัญชาติญาณของคลาสสิก
Radu GRIGore

1
@Radu: ขอบคุณที่ชี้ให้เห็นว่าสามารถทำได้โดยอัตโนมัติใน Coq ดังที่คุณได้กล่าวมาแล้วยังสามารถดึงข้อมูลที่สร้างสรรค์บางอย่างและดังนั้นโปรแกรมจากบทพิสูจน์คลาสสิกของทฤษฎีบทโดยใช้การทำเหมืองพิสูจน์สำหรับสูตรบางคลาส (ผู้ที่สนใจสามารถตรวจสอบรายละเอียดของเอกสารของUlrich Kuhlenbach ) ผลลัพธ์ที่เกี่ยวข้องอาจเป็นไปได้อีกอย่างหนึ่งว่าถ้าทฤษฎีบทได้รับการพิสูจน์ในมันก็สามารถพิสูจน์ได้ในโดยการแปลของฮาร์วีย์ฟรีดแมน _ P A H AΠ20PAHA
Kaveh

1
Andrej Bauer มีการโพสต์ใหม่ที่น่าสนใจในบล็อกของเขาซึ่งเขาพิสูจน์ให้เห็นการตีความ Dialectica เกอเดลใน Coq
Kaveh

18

สิ่งที่คุณจะถามเกี่ยวกับในคำถามแรกที่บางครั้งเรียกว่า "การตรวจสอบคอมไพเลอร์" และไม่กี่ปีที่ผ่านมาโทนีฮอร์นำเสนอว่ามันเป็นความท้าทายที่ยิ่งใหญ่สำหรับการวิจัยการคำนวณ ในระดับหนึ่งมีอยู่แล้วและมีการใช้งานอย่างแข็งขันในเครื่องมือต่าง ๆ เช่นCoq theorem proverซึ่งจัดระเบียบปัญหาด้วยวิธีการพิมพ์ทฤษฎีและข้อเสนอแบบ - ประเภท - หลักการ (" แกง - โฮเวิร์ด ")

แก้ไข: แค่ต้องการเพิ่มความสำคัญกับ "บางส่วน" สิ่งนี้อยู่ไกลจากปัญหาที่แก้ไขแล้ว แต่ความสำเร็จของ Coq นั้นให้ความหวังว่าไม่ใช่ความฝันที่น่าเบื่อหน่าย


8
ฉันจะบอกว่าการสร้างซอฟต์แวร์ที่ได้รับการยืนยันนั้นเป็นที่ที่การสร้างซอฟต์แวร์แบบธรรมดาในปี 1956 เป็นที่ชัดเจนแล้วว่าซอฟต์แวร์นั้นจะมีความสำคัญอย่างไม่น่าเชื่อและมีเรื่องราวความสำเร็จที่สำคัญอยู่แล้ว อย่างไรก็ตามผู้คนยังคงมีแนวคิดพื้นฐานที่ขาดหายไปมากมาย (ความเข้าใจอย่างชัดเจนว่าขั้นตอนและตัวแปรใดเป็นตัวอย่าง) และระยะทางจากทฤษฎีสู่การปฏิบัติอาจสั้นเท่ากับการนำ LISP ไปใช้โดยการเขียนโปรแกรมในทฤษฎีบท นี่เป็นช่วงเวลาที่น่าตื่นเต้นอย่างเหลือเชื่อที่จะทำงานเกี่ยวกับภาษาและการยืนยัน
Neel Krishnaswami

12

เครื่องมือที่ตรวจสอบว่าโปรแกรมนั้นถูกต้องหรือไม่บางครั้งเรียกว่าตัวตรวจสอบโปรแกรม ในบริบทนี้ "ถูกต้อง" มักจะหมายถึงสองสิ่ง: โปรแกรมไม่เคยสร้างผลลัพธ์บางอย่าง (คิดว่าการแบ่งส่วนผิดพลาด, NullPointerException, ฯลฯ ) และโปรแกรมเห็นด้วยกับข้อกำหนด

รหัสและข้อกำหนดอาจตกลงและยังถูกมองว่าผิด ในแง่หนึ่งการขอให้ผู้พัฒนาเขียนข้อกำหนดเป็นเหมือนการขอให้นักพัฒนาสองคนแก้ปัญหา หากการใช้งานทั้งสองตกลงกันคุณจะมีความมั่นใจมากขึ้นว่าจะยอมรับ อย่างไรก็ตามในอีกแง่หนึ่งข้อมูลจำเพาะนั้นดีกว่าการใช้งานครั้งที่สอง เนื่องจากสเปคนั้นไม่ต้องการประสิทธิภาพหรือแม้แต่การปฏิบัติการก็สามารถรวบรัดได้มากกว่าและยากที่จะผิด

ด้วยคำเตือนเหล่านี้ในใจผมขอแนะนำให้คุณมองไปที่ตรวจสอบ Spec # โปรแกรม


เท่าที่ฉันเข้าใจ Spec # (และส่วนขยาย Sing #) มันทำให้โปรแกรมเมอร์มีความสามารถในการตรวจสอบ asserts แต่ไม่ต้องการให้โปรแกรมเมอร์ทำสิ่งนี้และไม่ได้ให้ความสามารถในการพิสูจน์คุณสมบัติโดยพลการของโค้ด
Alex สิบ Brink

คุณสมบัติโดยพลการสามารถเข้ารหัสเป็นหลักการยืนยันได้ตามหลักการ ฉันไม่แน่ใจว่าคุณต้องการเครื่องมืออะไร คุณต้องการรายละเอียดที่จะพูดว่าสิ่งที่ควรจะเป็นสำหรับการส่งออกทั้งหมดหรือไม่
Radu GRIGore

4

ในกรณีทั่วไปเป็นไปไม่ได้ที่จะสร้างอัลกอริทึมที่ยืนยันว่าอัลกอริทึมนั้นเทียบเท่ากับสเปคหรือไม่ นี่คือหลักฐานที่ไม่เป็นทางการ:

เกือบทุกภาษาโปรแกรมทัวริงเสร็จสมบูรณ์ ดังนั้นภาษาใดก็ตามที่ TM ตัดสินใจสามารถถูกตัดสินโดยโปรแกรมที่เขียนด้วยภาษานี้

ปัญหาในการพิจารณาว่า TM สองตัวยอมรับภาษาเดียวกันหรือไม่ซึ่งเรียกว่านั้นไม่สามารถตัดสินใจได้ ผลที่ตามมาของทัวริงครบถ้วนถือเดียวกันสำหรับโปรแกรมของภาษาที่กำหนด กล่าวอีกนัยหนึ่งคือไม่สามารถตัดสินใจได้ว่าอินพุตที่คุณต้องการให้โปรแกรมของคุณยอมรับหรือไม่และอินพุตนั้นเหมือนกันจริงหรือไม่Equivalence/TM

นอกจากนี้นั้นไม่สามารถเรียกซ้ำได้ นั่นเป็นเพราะ (ระบุว่า TM ยอมรับอย่างน้อยหนึ่งอินพุต) หรือไม่นั้นเป็นภาษาที่ยอมรับได้เนื่องจากคุณสามารถวนซ้ำอินพุตที่เป็นไปได้ทั้งหมด หาก TM ไม่ว่างเปล่าในที่สุดคุณจะพบคำที่เป็นที่ยอมรับ ดังนั้นจึงไม่สามารถยอมรับได้มิฉะนั้นจะสามารถตัดสินใจได้ (ซึ่งเรารู้ว่ามันไม่ใช่) อย่างไรก็ตามความว่างเปล่า / TM สามารถลดลงเป็นดังนั้นจึงไม่สามารถยอมรับได้ ดังนั้นคุณสามารถใช้อัลกอริธึมว่าเครื่องสองเครื่องนั้นไม่เท่ากันหรือไม่ แต่คุณไม่สามารถแน่ใจได้ว่ามันเทียบเท่าหรือไม่ได้ให้อัลกอริทึมของคุณเพียงพอEquivalence/TMNonemptiness/TMEmptiness/TMEmptiness/TMEquivalence/TMEquivalence/TM

อย่างไรก็ตามนี่เป็นเพียงกรณีทั่วไป เป็นไปได้ว่าคุณสามารถตัดสินใจได้ว่าข้อมูลจำเพาะนั้นเทียบเท่ากับโปรแกรมหรือไม่โดยการแก้ไขปัญหาที่ผ่อนคลายมากขึ้น ตัวอย่างเช่นคุณอาจตรวจสอบเพียงอินพุตจำนวนหนึ่งหรือพูดว่าโปรแกรมทั้งสองนั้นเทียบเท่ากับความไม่แน่นอน นี่คือสิ่งที่ทดสอบซอฟต์แวร์เกี่ยวกับ

สำหรับคำถามที่เหลือของคุณ:

หมายเหตุ: ส่วนนี้ได้รับการแก้ไขเพื่อความกระจ่าง ปรากฎว่าฉันทำผิดพลาดที่ฉันพยายามหลีกเลี่ยงขอโทษ

ให้เป็นชุดของภาษาที่เรารู้ว่าสามารถตัดสินใจได้ แน่นอนR จากนั้นหนึ่งสามารถพิสูจน์ต่อไปนี้:TrueRTrueRR

ProvableR=TrueRtruer มันเป็นเรื่องง่ายที่จะเห็นว่าเซตที่แท้จริง แต่ก็ยังเป็นProvableR หลักฐานเป็นเรื่องง่ายมาก: Letแท้จริง ตามคำนิยามในทุกอินพุตส่งคืน YES หรือ NO ดังนั้นหยุดการทำงานทุกอินพุต มันตามที่ProvableRProvableRTrueRTrueRProvableRAϵTrueRAAAϵProvableR

อย่างไม่เป็นทางการซึ่งสามารถสรุปได้ดังนี้: คุณไม่ทราบว่าภาษานั้นสามารถตัดสินใจได้จนกว่าคุณจะพิสูจน์ได้ว่าเป็น ดังนั้นหากในระบบที่เป็นทางการคุณมีความรู้ว่าภาษานั้นสามารถตัดสินใจได้ความรู้นี้สามารถใช้เป็นหลักฐานในการพิสูจน์ได้ ดังนั้นคุณไม่สามารถมีความรู้พร้อมกันว่าทั้งสองภาษาสามารถถอดรหัสได้และไม่สามารถพิสูจน์ได้ดังนั้นงบสองคำนี้จึงไม่สามารถเกิดขึ้นพร้อมกันได้

จุดสุดท้ายของฉันอยู่ที่ความรู้ของเราเป็นบางส่วนและว่าวิธีเดียวของการศึกษาคือผ่านProvableRความแตกต่างอาจสมเหตุสมผลในวิชาคณิตศาสตร์และเราสามารถรับรู้ได้ แต่เราไม่มีเครื่องมือในการศึกษา เนื่องจากเราถูกผูกมัดว่าจะไม่รู้จักทั้งหมดอย่างสมบูรณ์RProvableRProvableRRR

@Kaveh สรุปว่าดีที่สุด: พิสูจน์ได้เสมอหมายถึงพิสูจน์ได้ในบางระบบ / ทฤษฎีและไม่ตรงกับความจริงโดยทั่วไป

การถือครองแบบเดียวกันสำหรับคลาสความซับซ้อนอื่น ๆ : ในการกำหนดความเป็นสมาชิกคุณต้องมีหลักฐานก่อน นี่คือเหตุผลที่ฉันเชื่อว่าคำถามที่สองของคุณกว้างเกินไปเนื่องจากมันมีเพียงทฤษฎีความซับซ้อนเท่านั้น แต่ยังรวมถึงทฤษฎีการคำนวณด้วยเช่นกันขึ้นอยู่กับคุณสมบัติที่คุณต้องการให้ภาษามี


1
บิตนั้นเกี่ยวกับดูเหมือนว่าคาวเล็กน้อย ทำไมต้องมีหลักฐานเพื่อให้ภาษาตัดสินใจได้? ที่จริงแล้วดูเหมือนว่าจะไม่มี (โดยทั่วไป): การพิจารณาว่าชุดการหยุดของ TM เป็นภาษาแบบเรียกซ้ำคือเสร็จสมบูรณ์หรือไม่ ถ้ามีหลักฐานว่าชุดลังเล TM ที่เป็นซ้ำมันจะอยู่ใน\RProvableRΣ30Σ10
Mark Reitblatt

1
พิสูจน์ได้เสมอหมายถึงพิสูจน์ได้ในบางระบบ / ทฤษฎีและไม่ตรงกับความจริงโดยทั่วไป
Kaveh

1
ตอนนี้ฉันเห็นแล้วว่าคำถามของฉันน่าสนใจใคร ๆ ก็ควรพูดถึงชุดของทัวริงที่หยุดนิ่งไม่ใช่ชุดของภาษาที่ decidable
Alex สิบ Brink

1
@ อเล็กซ์คุณต้องการวิธีพูดคุยเกี่ยวกับภาษา แต่มีหลายภาษาที่นับไม่ถ้วน ดังนั้นหากคุณต้องการพูดคุยเกี่ยวกับภาษาที่เชื่อมต่อกับวัตถุ จำกัด (เช่นหลักฐาน) คุณจำเป็นต้อง จำกัด ตัวเองเป็นภาษาที่สามารถระบุได้โดยวัตถุ จำกัด เช่น TM
Mark Reitblatt

2
chazisop อย่างที่ฉันพูดนั้นพิสูจน์ได้ว่าหมายถึงพิสูจน์ได้ในทฤษฎี (คงที่) และสำหรับทุกทฤษฎีที่สมเหตุสมผล (ce, สอดคล้อง, ... ) มีฟังก์ชั่นที่คำนวณได้ทั้งหมดซึ่งไม่สามารถพิสูจน์ได้ว่าเป็นทั้งหมดในทฤษฎีนั้น มีฟังก์ชันทั้งหมดที่ไม่สามารถพิสูจน์ได้ว่าเป็นผลรวมใน ZFC (และส่วนขยายที่สมเหตุสมผล) คุณกำลังสับสนแนวคิดเรื่องความจริงที่พิสูจน์ได้ ดังนั้นการพิสูจน์ไม่ทำงาน (สมมติว่าหมายถึงการเรียกซ้ำทั้งหมด) R
Kaveh

3

เอกสารการศึกษาแบบคลาสสิกต่อไปนี้เป็นการศึกษาคำถามที่สองของคุณเกือบทั้งหมด:

Hartmanis, J. การคำนวณที่เป็นไปได้และคุณสมบัติความซับซ้อนที่พิสูจน์ได้ , CBMS-NSF Regional Conference Series ในคณิตศาสตร์ประยุกต์, 30. สมาคมเพื่ออุตสาหกรรมและคณิตศาสตร์ประยุกต์ (SIAM), Philadelphia, Pa., 1978

ตัวอย่างเช่นเขากำหนดคลาส "F-TIME [T (n)]" (โดยที่ F คือระบบการพิสูจน์อย่างเป็นทางการที่สมเหตุสมผล) ให้เป็น (โดยเป็นเครื่องทัวริง i-th ในรายการทั้งหมดของ TM และเป็นเวลาทำงานสูงสุดของบน อินพุตของความยาว ) ฉันขอเน้นผลลัพธ์บางอย่างที่เกี่ยวข้องกับคำถามของคุณซึ่งมีอยู่อีกมากมายในเอกสารและการอ้างอิงใน:{L(Mi)|Ti(n)T(n) is provable in F}MiTi(n)Min

คร 6.4: ให้เป็นฟังก์ชันที่คำนวณได้และให้เป็นฟังก์ชันที่คำนวณได้มากมาย จากนั้น -(n)]กรัม( n ) 1 F T ฉันM E [ T ( n ) ] T ฉันM E [ T ( n ) กรัม( n ) ]T(n)nlog(n)g(n)1FTIME[T(n)]TIME[T(n)g(n)]

ทฤษฎีบท 6.5: มีอยู่คำนวณ monotonically เวลาการเพิ่มขอบเขตที่ -(n)]T(n)FTIME[T(n)]TIME[T(n)]

ทฤษฎีบท 6.14: สำหรับการคำนวณ ,\}T(n)nlog(n)TIME[T(n)]={L(Mi)|F proves(j)[L(Mj)=L(Mi)Tj(n)T(n)]}

สำหรับพื้นที่อย่างไรก็ตามสถานการณ์นั้นควบคุมได้ดีกว่า:

ทฤษฎีบท 6.9 (1) หากเป็นพื้นที่ constructible แล้ว -(n)]s(n)nSPACE[s(n)]=FSPACE[s(n)]

(2) ถ้า - ( ) ดังนั้นจะมีช่องว่างที่สร้างได้เช่นนั้น(n)]S P A C E [ S ( n ) ] S ( n ) n s ( n ) S P A C E [ S ( n ) ] = S P A C E [ s ( n ) ]SPACE[S(n)]=FSPACE[S(n)]S(n)ns(n)SPACE[S(n)]=SPACE[s(n)]


1

คำถามจะต้องถูกวางอย่างถูกต้อง ตัวอย่างเช่นไม่มีใครอยากรู้ว่าโปรแกรมจริงจะเสร็จสมบูรณ์หรือไม่โดยใช้หน่วยความจำที่ไม่มีที่สิ้นสุดและใช้วิธีการบางอย่างในการเข้าถึงมัน (อาจเป็นการดำเนินการเพื่อย้ายฐานที่อยู่ด้วยตัวเลข) ทฤษฎีของทัวริงนั้นไม่เกี่ยวข้องกับความถูกต้องของโปรแกรมในแง่ที่เป็นรูปธรรมและผู้คนที่อ้างถึงว่าเป็นอุปสรรคในการตรวจสอบโปรแกรมทำให้สับสนสองสิ่งที่แตกต่างกัน เมื่อวิศวกร / โปรแกรมเมอร์พูดถึงความถูกต้องของโปรแกรมพวกเขาต้องการทราบคุณสมบัติที่แน่นอน นี่ก็เป็นความจริงสำหรับนักคณิตศาสตร์ที่สนใจว่ามีบางสิ่งที่พิสูจน์ได้ จดหมายของ Godel http://vyodaiken.com/2009/08/28/godels-lost-letter/อธิบายรายละเอียดนี้

เห็นได้ชัดว่ามันหมายถึงว่าทั้งๆที่ undecidability ของ Entscheidungsproblem งานจิตของนักคณิตศาสตร์ที่เกี่ยวข้องกับคำถามใช่หรือไม่ก็สามารถถูกแทนที่ด้วยเครื่องได้อย่างสมบูรณ์ ท้ายที่สุดแล้วใคร ๆ ก็ต้องเลือกหมายเลขธรรมชาติที่มีขนาดใหญ่จนเมื่อเครื่องไม่ได้ผลลัพธ์มันไม่มีเหตุผลที่จะต้องคิดถึงปัญหามากขึ้น

อาจเป็นไปไม่ได้ที่จะตรวจสอบชุดสถานะอันยิ่งใหญ่ของโปรแกรมที่ทำงานบนคอมพิวเตอร์จริงและตรวจจับสถานะที่ไม่ดีไม่มีเหตุผลทางทฤษฎีว่าทำไมจึงไม่สามารถทำได้ ในความเป็นจริงมีความคืบหน้ามากมายในสาขานี้ - ตัวอย่างเช่นดูhttp://www.cs.cornell.edu/gomes/papers/SATSolvers-KR-book-draft-07.pdf (ขอบคุณ Neil Immerman สำหรับ บอกฉันเกี่ยวกับเรื่องนี้)

ปัญหาที่แตกต่างและยากขึ้นคือการระบุคุณสมบัติที่ต้องการให้โปรแกรมมีความถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.