การเรียกซ้ำของคำนำในผลรวมของจำนวนธรรมชาติ n จำนวน

ฉันมีปัญหาในการเข้าใจว่าค่าของ Z เปลี่ยนแปลงตลอดเวลาอย่างไร ขั้นตอนเฉพาะได้รับการระบุไว้ในเอาต์พุตการติดตามสแต็ก

นี่คือโค้ดที่ฉันใช้หาผลรวมของจำนวนธรรมชาติ N -

sum1(1,1).
sum1(N, Sum) :-
   Next is N-1,
   sum1(Next, Z),
   Sum is Z + N.

นี่คือการติดตามสแต็ก -

?- sum1(3,_).
   Call: (8) sum1(3, _2668) ? creep
   Call: (9) _2860 is 3+ -1 ? creep
   Exit: (9) 2 is 3+ -1 ? creep
   Call: (9) sum1(2, _2862) ? creep
   Call: (10) _2866 is 2+ -1 ? creep
   Exit: (10) 1 is 2+ -1 ? creep
   Call: (10) sum1(1, _2868) ? creep
   Exit: (10) sum1(1, 1) ? creep
   Call: (10) _2872 is 1+2 ? creep
   Exit: (10) 3 is 1+2 ? creep
   Exit: (9) sum1(2, 3) ? creep **%How is Z assigned value 3 ?**
   Call: (9) _2668 is 3+3 ? creep
    Exit: (9) 6 is 3+3 ? EOF: exit

ขอบคุณล่วงหน้า!


person Markandeya    schedule 09.04.2018    source แหล่งที่มา
comment
โดยพื้นฐานแล้ว ตัวแปรจะถูกกำหนดขอบเขตตามการเรียกที่ตัวแปรนั้นอยู่ ตัวแปรใดๆ ระหว่างการเรียกจะได้รับการกำหนดตัวแปรที่ไม่ระบุชื่อใหม่จนกว่าจะรวมเป็นหนึ่งเดียวกับสิ่งที่ถูกส่งผ่านไป ซึ่งหมายความว่า หากคุณใช้ Z ในหลายตำแหน่ง Z จะไม่เกิดขึ้นทันที และพูดว่า Z = A จะมีการสร้างตัวแปรที่ไม่ระบุชื่อใหม่ _1234 ขึ้น ซึ่งกำหนดให้กับทั้ง A และตำแหน่งทั้งหมดที่ใช้ Z   -  person G_V    schedule 10.04.2018


คำตอบ (1)


มันไม่ได้ "เปลี่ยนแปลง"; แต่ละหลักฐานของ sum1 จะมีเวอร์ชัน N, Sum, Next และ Z ของตัวเอง นี่คือเหตุผลว่าทำไมในการติดตามสแต็ก แต่ละชื่อจึงสร้างชื่อที่แตกต่างกัน (เช่น _2860) ดังนั้น Prolog จึงสามารถแยกความแตกต่างได้

สำหรับคำถามเฉพาะของคุณ มี 2 บรรทัดเหนือบรรทัดที่คุณถาม Sum นั้นคือ _2872; ดังนั้นการพิสูจน์ _2872 is 1+2 ต้องใช้ _2872 เป็น 3 และ Sum นี้ตรงกับการโทรก่อนหน้า sum(1, _2868) โดยที่ _2868 คือ sum1's Z (ดังที่คุณเห็นจาก 2 บรรทัดด้านบนนั้น)

person Scott Hunter    schedule 09.04.2018
comment
ดังนั้น 3 ได้รับการกำหนดให้ sum1(2, _2862) เนื่องจากคำนำตรงกับการโทรครั้งก่อน - person Markandeya; 09.04.2018
comment
3 กำลังได้รับมอบหมายให้ _2862 - person Scott Hunter; 09.04.2018