การทดสอบผู้ชายหรือเด็กชาย
การทดสอบชายหรือเด็กชายได้รับการเสนอโดยนักวิทยาศาสตร์คอมพิวเตอร์Donald Knuthเพื่อเป็นวิธีการประเมินการใช้งาน ภาษาโปรแกรม ALGOL 60จุดประสงค์ของการทดสอบคือการแยกแยะคอมไพเลอร์ที่ใช้งาน " การเรียกซ้ำและการอ้างอิงที่ไม่ใช่โลคอล " ได้อย่างถูกต้องจากคอมไพเลอร์ที่ใช้งานไม่ได้[ 1 ]
มีตัวแปลภาษา ALGOL60 อยู่หลายตัวที่ออกแบบมาเพื่อจัดการกับการเรียกซ้ำและการอ้างอิงที่ไม่ใช่แบบโลคอลได้อย่างถูกต้อง และผมคิดว่าโปรแกรมทดสอบเล็กๆ อาจมีประโยชน์ ดังนั้นผมจึงเขียนรูทีนง่ายๆ ต่อไปนี้ ซึ่งอาจช่วยแยกแยะคอมไพเลอร์ที่เชี่ยวชาญออกจากคอมไพเลอร์มือใหม่ได้
— โดนัลด์ คนูธ[ 2 ]
ตัวอย่างของคนูธ
ในALGOL 60 :
เริ่มขั้นตอนจริงA ( k , x1 , x2 , x3 , x4 , x5 ) ; ค่าk ; จำนวนเต็มk ; จำนวนจริงx1 , x2 , x3 , x4 , x5 ; เริ่มขั้นตอนจริงB ; เริ่มk := k - 1 ; B := A := A ( k , B , x1 , x2 , x3 , x4 ) สิ้นสุด; ถ้าk ≤ 0 แล้วA := x4 + x5 มิฉะนั้นB สิ้นสุด; outreal ( 1 , A ( 10 , 1 , - 1 , - 1 , 1 , 0 )) สิ้นสุดสิ่งนี้สร้างโครงสร้างต้นไม้ของ เฟรมการเรียก Bที่อ้างอิงถึงกันและกัน และอ้างอิงถึง เฟรมการเรียก A ที่บรรจุอยู่ โดย แต่ละเฟรมการเรียก A จะมีสำเนาของk เป็นของตัวเอง ซึ่งจะเปลี่ยนแปลงทุกครั้งที่มี การเรียก B ที่เกี่ยวข้อง การพยายามคำนวณบนกระดาษอาจไร้ประโยชน์ แต่สำหรับk = 10 คำตอบที่ถูกต้องคือ −67 แม้ว่าในบทความต้นฉบับ Knuth จะคาดการณ์ว่าคำตอบคือ −121 ก็ตาม แม้แต่เครื่องคอมพิวเตอร์ที่ทันสมัยก็ยังใช้ พื้นที่ สแต็ก หมดอย่างรวดเร็ว สำหรับค่าk ที่มากขึ้น ซึ่งแสดงไว้ในตารางด้านล่าง ( OEIS : A132343 )
| เค | |
|---|---|
| 0 | 1 |
| 1 | 0 |
| 2 | −2 |
| 3 | 0 |
| 4 | 1 |
| 5 | 0 |
| 6 | 1 |
| 7 | −1 |
| 8 | −10 |
| 9 | −30 |
| 10 | −67 |
| 11 | −138 |
| 12 | −291 |
| 13 | −642 |
| 14 | −1446 |
| 15 | −3250 |
| 16 | −7244 |
| 17 | −16 065 |
| 18 | −35 601 |
| 19 | −78 985 |
| 20 | −175 416 |
| 21 | −389 695 |
| 22 | −865 609 |
| 23 | −1 922 362 |
| 24 | −4 268 854 |
| 25 | −9 479 595 |
| 26 | −21 051 458 |
คำอธิบาย
มีคุณลักษณะของ Algol สามอย่างที่ใช้ในโปรแกรมนี้ ซึ่งอาจเป็นเรื่องยากที่จะนำไปใช้งานอย่างถูกต้องในคอมไพเลอร์:
- การนิยามฟังก์ชันแบบซ้อนกัน : เนื่องจาก Bถูกนิยามในบริบทเฉพาะที่ของ Aดังนั้นตัวฟังก์ชัน Bจึงสามารถเข้าถึงสัญลักษณ์ที่เป็นเฉพาะที่ของ A ได้ โดยเฉพาะอย่างยิ่ง kซึ่งมันถูกแก้ไข แต่ยังรวมถึง x1 , x2 , x3 , x4และ x5 ด้วย สิ่งนี้ทำได้ง่ายในภาษา Pascal ซึ่งเป็นภาษาที่สืบทอดมาจาก Algol แต่เป็นไปไม่ได้ในภาษา Cซึ่งเป็นภาษาที่สืบทอดมาจาก Algol อีกภาษาหนึ่ง(เว้นแต่จะจำลองกลไกนี้ด้วยตนเองโดยใช้ตัวดำเนินการ address-of ของ C โดยการส่งพอยเตอร์ไปยังตัวแปรเฉพาะที่ระหว่างฟังก์ชันต่างๆ)
- การอ้างอิงฟังก์ชัน : ตัว Bในการเรียกแบบเรียกซ้ำนั้น
A(k, B, x1, x2, x3, x4)ไม่ใช่การเรียกใช้ฟังก์ชัน Bโดยตรง แต่เป็นการอ้างอิงถึงฟังก์ชัน Bซึ่งจะถูกเรียกใช้ก็ต่อเมื่อ kมีค่ามากกว่าศูนย์เท่านั้น วิธีการนี้เข้าใจง่ายในภาษาปาสคาลมาตรฐาน ( ISO 7185 ) และในภาษาซีด้วย ปาสคาลบางเวอร์ชัน (เช่นเทอร์โบปาสคาล เวอร์ชันเก่า) ไม่รองรับการอ้างอิงฟังก์ชันแบบโปรซีเจอร์ แต่เมื่อทราบชุดของฟังก์ชันที่อาจถูกอ้างอิงไว้ล่วงหน้า (ในโปรแกรมนี้คือฟังก์ชัน Bเท่านั้น) ก็สามารถแก้ไขปัญหานี้ได้ - ความเป็นคู่ของค่าคงที่/ฟังก์ชัน : พารามิเตอร์ x1ถึงx5ของAอาจเป็นค่าคงที่ตัวเลขหรือการอ้างอิงถึงฟังก์ชันB —
x4 + x5นิพจน์จะต้องเตรียมพร้อมที่จะจัดการทั้งสองกรณีราวกับว่าพารามิเตอร์อย่างเป็นทางการx4และx5ได้ถูกแทนที่ด้วยพารามิเตอร์จริงที่สอดคล้องกัน ( เรียกตามชื่อ ) [ 3 ]นี่อาจเป็นปัญหามากกว่าใน ภาษา ที่มีการกำหนดประเภทแบบคงที่มากกว่าในภาษาที่มีการกำหนดประเภทแบบไดนามิก แต่วิธีแก้ปัญหามาตรฐานคือการตีความค่าคงที่ 1, 0 และ −1 ในการเรียกหลักของA ใหม่ เป็นฟังก์ชันที่ไม่มีอาร์กิวเมนต์ที่ส่งคืนค่าเหล่านี้
อย่างไรก็ตาม สิ่งเหล่านี้ไม่ใช่ประเด็นหลักของการทดสอบ แต่เป็นเพียงข้อกำหนดเบื้องต้นเพื่อให้การทดสอบมีความหมาย ประเด็นหลักของการทดสอบคือการตรวจสอบว่าการอ้างอิงถึงB ที่แตกต่างกันนั้น ชี้ไปยัง อินส แตนซ์ของB ที่ ถูกต้อง หรือไม่ ซึ่งก็คืออินสแตน ซ์ที่มีสิทธิ์เข้าถึงสัญลักษณ์เฉพาะที่ของA เช่นเดียวกับ Bที่สร้างการอ้างอิงนั้น ตัวอย่างเช่น คอมไพเลอร์แบบ "boy" อาจคอมไพล์โปรแกรมเพื่อให้B เข้าถึง เฟรมการเรียกAระดับบนสุดเสมอ
ดูเพิ่มเติม
ลิงก์ภายนอก
- ตัวอย่าง การทดสอบผู้ชายหรือเด็กผู้ชายในภาษาโปรแกรมหลายภาษา