while 语言

发布于 2024-07-13 07:01:37 字数 775 浏览 8 评论 0原文

在我的计算语言理论课程中,我们接到了一项作业,要求用一种只有 while 语句进行流程控制(没有 if 语句)的语言来实现一段代码。 这主要是为了证明只用while循环就可以写出图灵完备的语言。

对于那些能够理解语言语法的人,这里是语言规则:

S -> S;S | while C do S od | id := E

E -> E + T | T | E - T

T -> T * F | F | F / T

F -> id | cons | (E)

C -> E = E | E > E | E < E | E >= E | E <= E | E != E | C and C | C or C | not(C)

这是从我的课堂笔记中复制的,所以如果有遗漏或不正确的地方,请不要怪我!

要实现的代码片段是这样的:

if d = 0 do
    x := 1
else
    x := a / d

无论如何,如果您想继续使用上面的语言规则编写代码,那就继续吧。 否则,请继续用您最熟悉的任何语言编写它。但有一些注意事项!

  • 除了 while 循环之外,没有 if 语句或任何其他类型的流程控制。
  • 没有作弊:上面的语法不包括任何break语句、return语句或异常。 不要使用它们。

我已经为此编写了一段代码(我发布它只是为了证明这不是一个向我展示代码的帖子)。 我有点好奇其他人能想出什么。

For my theory of computing languages class, we got a homework assignment to implement a piece of code in a language that only has while statements for flow control (no if statements). This is mainly to prove that you can write a Turing-complete language with only a while loop.

For those of you who can understand language grammars, here are the language rules:

S -> S;S | while C do S od | id := E

E -> E + T | T | E - T

T -> T * F | F | F / T

F -> id | cons | (E)

C -> E = E | E > E | E < E | E >= E | E <= E | E != E | C and C | C or C | not(C)

This is copied from my class notes, so don't blame me if something is missing or incorrect!

The piece of code to implement is this:

if d = 0 do
    x := 1
else
    x := a / d

At any rate, if you want to go ahead and write that using the language rules above, go ahead. Otherwise, go ahead and write it in whatever language you're most comfortable in. But there are a few caveats!

  • No if statements or any other kind of flow control other than while loops.
  • No cheating: the grammar above doesn't include any break statements, return statements, or exceptions. Don't use them.

I've got my piece of code written for this (which I'll post just to prove this isn't a show me teh codez post). I'm kinda curious what anyone else can come up with though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

橪书 2024-07-20 07:01:37

它可以用一个 while 循环来完成,但不太清楚:

while d == 0 do
  d := 1;
  a := 1
od
x := a / d;

解释,如果 d = 0,那么 d 将是 1,a 也将是 1。这结束了循环。

现在 x 设置为 a / d ,这很好,因为如果 d 为 0,则 a / d 的计算结果为 1。

It can be done with a single while loop, but it is not that clear:

while d == 0 do
  d := 1;
  a := 1
od
x := a / d;

Explanation, if d = 0, then d will be 1, also a will be 1. This ends the loop.

Now x is set to a / d which is fine, because if d was 0, a / d evaluates to 1.

情绪少女 2024-07-20 07:01:37

这是我的代码:

continue := True
while d = 0 and continue do
    x := 1
    continue := False
od
while d != 0 and continue do
    x := a/d
    continue := False
od

Here's my code:

continue := True
while d = 0 and continue do
    x := 1
    continue := False
od
while d != 0 and continue do
    x := a/d
    continue := False
od
━╋う一瞬間旳綻放 2024-07-20 07:01:37

这行得通吗?

td := d
x := 1

while td != 0 do
    x := a / d
    td := 0
od

Would this work?

td := d
x := 1

while td != 0 do
    x := a / d
    td := 0
od
黯淡〆 2024-07-20 07:01:37

要实现图灵完备,您需要支持选择和迭代。 While 循环显然是迭代的。 如果条件为真,则可以通过使其循环一次来完成选择,否则根本不循环。

因此,在最坏的情况下,您可以通过应用这些技术来完成您需要做的一切。 我想一些复杂的控制流程会很快变得丑陋。 :-)

To be Turing Complete, you need to support both selection and iteration. While loops obviously iterate. Selection can be accomplished by making it go through the loop once if the condition is true, and not at all otherwise.

So worst case you can do everything you need to by applying those techniques. I'd imagine some complicated control flows would get ugly fast though. :-)

莫言歌 2024-07-20 07:01:37

不使用 true 或 false 分支的详细信息,也不重复谓词:

statementIncomplete := True
while d = 0 and statementIncomplete do
    x := 1
    statementIncomplete := False
od
while statementIncomplete do
    x := a/d
    statementIncomplete := False
od

Without using details of the true or false branches, and without repeating the predicate:

statementIncomplete := True
while d = 0 and statementIncomplete do
    x := 1
    statementIncomplete := False
od
while statementIncomplete do
    x := a/d
    statementIncomplete := False
od
网名女生简单气质 2024-07-20 07:01:37

这是Eamon 的答案的扩展。

if的语义 然后否则fi 如下:

  • 评估;
  • 如果为 true,则执行 thenelse 之间的语句;
  • 否则,执行elsefi之间的语句。

while的语义 做od 如下:

  • 评估 ;
  • 如果为 false,则 while 语句执行完毕;
  • 否则,执行dood之间的语句,并再次执行while语句。

要用 while 表达 if A then B else C,请执行以下转换:

gensymN 为不用于任何其他变量的名称; 然后发出以下代码

gensymN := 0;
while gensymN = 0 and A do B; gensymN = 1; od;
while gensymN = 0 do C; gensymN = 1; od

该程序的语义是:

  • 将 0 分配给 gensymN 。
  • 评估 gensymN = 0 和 A(如果 A 为真,则为真)
  • 如果为真,则:
    • 执行B
    • 执行gensymN = 1
    • 评估gensymN = 0 和 A(错误)
    • 评估gensymN = 0(错误)
  • else(如果 gensymN = 0 且 A 为假):
    • 评估gensymN = 0(这是真的)
    • 执行C
    • 执行gensymN := 1
    • 评估gensymN = 0(错误)

观察上面的以下子结构:

  • 它(有效地)评估A
  • 如果为 true,则执行 B,否则执行 C
  • 除了 ABC 之外,程序(片段)仅对 gensymN 进行摆弄,而 gensymN 并不存在在输入程序中。

因此,这个程序与一个脚注具有相同的语义

if A then B else C fi; gensymN := 1

:如果A在求值时为真,它将再次求值(除非and是短路的)。 如果语言允许在变量中存储布尔值,则可以再引入一个虚拟变量并执行 dummy := A; <在此处插入上述程序,用虚拟代替 A>。 那么 dummy 的两次评估本质上只是一个负载。 如果评估布尔表达式不会产生副作用,则不必为了正确性而阻止第二次评估; 它可能是(也可能不是)优化。

将上述内容作为“软证明”,加上前一段的附加条件,这是 ifwhile完全通用翻译>。 在我看来,完整的普遍性使这个(=埃蒙的)答案与其他答案区分开来。

This is an expansion of Eamon's answer.

The semantics of if <condition> then <stmt> else <stmt> fi is the following:

  • evaluate <condition>;
  • if it was true, execute the statement between then and else;
  • otherwise, execute the statement between else and fi.

The semantics of while <condition> do <stmt> od is the following:

  • evaluate <condition>;
  • if false, the while statement is done executing;
  • otherwise, execute the statement between do and od, and execute the while statement again.

To express if A then B else C in terms of while, perform the following transformation:

Let gensymN be a name not used for any other variable; then emit the following code

gensymN := 0;
while gensymN = 0 and A do B; gensymN = 1; od;
while gensymN = 0 do C; gensymN = 1; od

The semantics of this program is:

  • Assign 0 to gensymN.
  • Evaluate gensymN = 0 and A (it's true iff A is true)
  • If true, then:
    • execute B
    • execute gensymN = 1
    • evaluate gensymN = 0 and A (it's false)
    • evaluate gensymN = 0 (it's false)
  • else (if gensymN = 0 and A was false):
    • evaluate gensymN = 0 (it's true)
    • execute C
    • execute gensymN := 1
    • evaluate gensymN = 0 (it's false)

Observe the following substructure of the above:

  • It (effectively) evaluates A;
  • If true, it executes B, otherwise C.
  • Apart from A, B and C, the program (fragment) only fiddles with gensymN, which is not present in the input program.

Hence this program has the same semantics as

if A then B else C fi; gensymN := 1

One footnote: if A is true when evaluated, it will be evaluated once again (unless and is short-circuiting). If the language allows storing booleans in variables, one can introduce one more dummy variable and do dummy := A; <insert the above program here, with dummy instead of A>. Then the two evaluations of dummy are essentially just a load. If evaluating boolean expressions cannot have side effects, preventing the second evaluation is not necessary for correctness; it may (or may not) be an optimization.

Take the above as a "soft proof", with the provisos of the preceding paragraph, that this is a correct fully general translation of if to while. The full generality sets this (= Eamon's) answer apart from the others, in my view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文