เหตุใดฟังก์ชันที่คำนวณได้จึงเรียกว่าฟังก์ชันแบบเรียกซ้ำ


23

ในทฤษฎีการคำนวณฟังก์ชันการคำนวณก็เรียกว่าฟังก์ชันแบบเรียกซ้ำ อย่างน้อยแรกพบพวกเขาไม่มีอะไรเหมือนกันกับสิ่งที่คุณเรียกว่า "recursive" ในการเขียนโปรแกรมแบบวันต่อวัน (เช่นฟังก์ชั่นที่เรียกพวกเขาเอง)

ความหมายที่แท้จริงของการเกิดซ้ำในบริบทของการคำนวณคืออะไร? ทำไมฟังก์ชั่นเหล่านี้จึงเรียกว่า "เวียนเกิด"?

หากต้องการกล่าวไว้ในคำอื่น ๆ : การเชื่อมต่อระหว่างสองความหมายของ "การเรียกซ้ำ" คืออะไร?



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

3
มีฟังก์ชั่นการเรียกซ้ำแบบดั้งเดิมหรือไม่ คัดลอกมาจากวิกิพีเดียพวกเขาถูกกำหนดเป็นและh ( S ( y ) , x 1 , , x k ) = g ( y , h ( y , x 1 , ...h(0,x1,,xk)=f(x1,,xk) ) นั่นคือฟังก์ชั่นที่เรียกตัวเองว่า h(S(y),x1,,xk)=g(y,h(y,x1,,xk),x1,...,xk)
Hendrik Jan

3
@GoloRoden โปรดทราบว่าคำอธิบายแท็กของ 'ความสามารถในการคำนวณ' (คุณใช้สำหรับคำถามนี้) พูดว่า: "ทฤษฎีการคำนวณความสามารถหรือที่เรียกว่าทฤษฎีการเรียกซ้ำ" Gödelเรียกว่าฟังก์ชั่นrecursiveแต่คำว่าการพัฒนาที่จะคำนวณ อาจจะหลีกเลี่ยงความสับสนเช่นคุณ ผู้ที่ศึกษาทฤษฎีการคำนวณ (อย่างหนาแน่น) มีแนวโน้มที่จะใช้ทฤษฎีการเรียกซ้ำคำว่า 'เคารพ' รากของมัน
Auberon

1
เพราะฟังก์ชันเหล่านั้นถูกกำหนดแบบวนซ้ำนั่นคือ " มีการกำหนดฟังก์ชันที่ซับซ้อนมากขึ้นในแง่ของฟังก์ชั่นที่กำหนดไว้ก่อนหน้านี้ "
Nikos M.

คำตอบ:


13

กำหนดฟังก์ชั่นพื้นฐานบางอย่าง:

  • ฟังก์ชั่นศูนย์

    ZอีRโอ:ยังไม่มีข้อความยังไม่มีข้อความ:x0
  • ฟังก์ชันตัวตายตัวแทน

    sยู:ยังไม่มีข้อความยังไม่มีข้อความ:xx+1
  • ฟังก์ชั่นการฉาย

pin:NnN:(x1,x2,,xn)xi

จากนี้ไปฉันจะใช้เพื่อแสดง( x 1 , x 2 , , x n )xn¯(x1,x2,,xn)

กำหนดองค์ประกอบ:

ฟังก์ชั่นที่กำหนด

  • แต่ละคนมีลายเซ็น N kNg1,g2,,gmNkN
  • f:NmN

สร้างฟังก์ชั่นต่อไปนี้:

ชั่วโมง:ยังไม่มีข้อความkยังไม่มีข้อความ:xk¯ชั่วโมง(xk¯)=(ก.1(xk¯),ก.2(xk¯),...,ก.ม.(xk¯))

กำหนดการเรียกซ้ำแบบดั้งเดิม:

ฟังก์ชั่นที่กำหนด

  • :ยังไม่มีข้อความkยังไม่มีข้อความ
  • ก.:ยังไม่มีข้อความk+2ยังไม่มีข้อความ

สร้างฟังก์ชั่นดังต่อไปนี้ (ชิ้นส่วน):

ชั่วโมง:ยังไม่มีข้อความk+1ยังไม่มีข้อความ:(xk¯,Y+1){(xk¯),Y+1=0ก.(xk¯,Y,ชั่วโมง(xk¯,Y)),Y+1>0

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

คำจำกัดความและการก่อสร้างด้านบนนี้สร้างโดยGödel (มีคนไม่กี่คนที่เกี่ยวข้องด้วย) ในความพยายามที่จะจับฟังก์ชั่นทั้งหมดที่คำนวณได้นั่นคือมีทัวริงสำหรับฟังก์ชันนั้น โปรดทราบว่าแนวคิดของเครื่องทัวริงยังไม่ได้อธิบายหรืออย่างน้อยก็คลุมเครือมาก

(ยกเลิก) โชคดีมีคนเรียก Ackermann มาและกำหนดหน้าที่ต่อไปนี้:

  • Ack:N2N
  • Ack(0,y)=y+1
  • Ack(x+1,0)=Ack(x,1)
  • Ack(x+1,y+1)=Ack(x,Ack(x+1,y))

This function is computable, but there's no way to construct it using only the constructions above! (i.e. Ack is not primitive recursive) This means that Gödel and his posse failed to capture all computable functions in their construction!

Gödel had to expand his class of functions so Ack could be constructed. He did this by defining the following:

Unbounded minimisation

  • g:NkN
  • IF [f(xk¯,y)=0 AND f(xk¯,z) is defined z<y AND f(xk¯,z)0]
    THEN
    g(xk¯)=y
    ELSE
    g(xk¯) is not defined.

This last one may be hard to grasp, but it basically means that g((x1,x2,,xk)) is the smallest root of f (if a root exists).


All functions that can be constructed with all the constructions defined above are called recursive. Again, the name recursive is just by definition, and it doesn't necessarily have correlation with functions that call themselves. Truly, consider it a homonym.

Recursive functions can be either partial recursive functions or total recursive functions. All partial recursive functions are total recursive functions. All primitive recursive functions are total. As an example of a partial recursive function that is not total, consider the minimisation of the successor function. The successor function doesn't have roots, so its minimisation is not defined. An example of a total recursive function (which uses minimisation) is Ack.

Now Gödel was able to construct the Ack function as well with his expanded class of functions. As a matter of fact, every function that can be computed by a Turing machine, can be represented by using the constructions above and vice versa, every construction can be represented by a Turing machine.

If you're intrigued, you could try to make Gödel's class bigger. You can try to define the 'opposite' of unbounded minimisation. That is, unbounded maximisation i.e. the function that finds the biggest root. However, you may find that computing that function is hard (impossible). You can read into the Busy Beaver Problem, which tries to apply unbounded maximisation.


4
I know realise the given definitions don't really answer the question, but my answer describes the evolution of recursion/computability theory, kind of. Might be worth a read.
Auberon

I like it, thanks for your efforts :-)
Golo Roden

In "if h((x1,x2,...,xk),0)=f((x1,x2,...,xk))", I think you mean h((x1,x2,...,xk,0)). Also, there is no then clause prior to the next bullet point's else clause.
Eric Towers

2
Afaik, this is subtly wrong. The set if μ-recursive functions is called the set of partially recursive functions whereas recursive functions are always total. That's why the set of all total functions (resp. languages that can be decided) is called R.
Raphael

1
There are quite a few incorrect statements in your answer. You should not make up history for an answer.
Kaveh

17

The founders of computability theory were mathematicians. They founded what is now called computability theory before there was any computers. What was the way mathematicians defined functions that could be computed? By recursive definitions!

So there were recursive function before there were any other model of computation like Turing machines or lambda calculus or register machines. So people referred to these function as recursive functions. The fact that they turned out to be exactly what Turing machines and other models can compute is a later event (mostly proven by Kleene).

We have the simple definition of a recursive function which is now called primitive recursive function. There were not general enough (e.g. Ackermann's function) so people developed more general notions like μ-recursive functions and Herbrand-Gödel general recursive functions that did capture all computable functions (assuming the Church's thesis). Church claimed that his model of lambda calculus captured all computable functions. Many people, and in particular Gödel, were not convinced that these capture all functions that can be computed. Until Turing's analysis of computation and introduction of his machine model.

The name of the field used to recursion theory. However there has been a successful push in recent decades to change the name to something more appealing from recursion theory to something more computer sciency (vs. mathy). As a result the field is now called computability theory. However if you look at books, papers, conferences, etc. in the early decades they are called recursion theory and not computability theory. Even the title of Soare's own 1987 book (who was the main person behind the push to change the name to computability theory) is "Recursively Enumerable Sets and Degrees".

If you want to know more about the history a fun and good place to read about it is the first chapter of Classical Recursion Theory by Odifreddi.


7

Robert Soare wrote an essay about this issue. According to him, the term (general) recursive functions was coined by Gödel, who defined them using some sort of mutual recursion. The name stuck, though later on other equivalent definitions were found.

For more information, I recommend Soare's essay.


0

instead of putting a long comment decided to add an answer:

Because they are defined recursively, i.e "more complex functions are defined in terms of previously defined, simpler functions"

This kind of iterative or incremental procedure creates well-defined functions (in the mathematical sense)

This is the meaning of recursiveness in mathematical parlance. See below how this relates to recursion in programming parlance.

Compare this procedure with techniques and methods like (mathematical) induction which is also an example of recursiveness in mathematics.

Programming has a mathematical vein as well as an engineering one.

This (usualy constructive) procedure is also refered as "bootstrapping" in Operating Systems parlance.

However a runtime recursion of the same function (i.e caling itself during its runtime), since it must (hmm, should) happen on already computed values (or arguments), or in other words, in the part of the result set already computed, is also recursive in the above sense, i.e "defined w.r.t previously defined functions (and their values)"

Else is not well-defined, and leads to such things like Stack Overflow :))))

เพื่อให้ตัวอย่างเพิ่มเติมจากระบบปฏิบัติการสามารถเรียกใช้การเรียกใช้รันไทม์ (เรียกตัวเอง) เป็นอะนาล็อกของการรีบูตระบบปฏิบัติการหลังจากการอัปเดตบางอย่าง (เช่นการอัปเดตหลัก) ระบบปฏิบัติการหลายตัวทำตามขั้นตอนต่อไปนี้:

  1. การบูตเริ่มต้นเพื่อโหลดรูทีนระดับต่ำ (เช่น I / O)
  2. ทำการอัพเดตที่จำเป็น (โดยใช้รูทีนระดับต่ำ)
  3. บูตใหม่ (อย่างมีประสิทธิภาพเรียกตัวเองใหม่) แต่คราวนี้โหลดกิจวัตรที่ซับซ้อนมากขึ้น (หรือแม้กระทั่งระบบทั้งหมด)

คำตอบที่สวยงามของ Auberonแสดงให้เห็นถึงขั้นตอนนี้อย่างละเอียด

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