Halting problem(停机问题)

原创 2016年06月02日 00:40:51

1.Introduction

In computability theory, the halting problem is the problem of determining, from a description of an arbitrary computer program and an input, whether the program will finish running or continue to run forever.

The halting problem is a decision problem about properties of computer programs on a fixed Turing-complete model of computation, i.e., all programs that can be written in some given programming language that is general enough to be equivalent to a Turing machine. The problem is to determine, given a program and an input to the program, whether the program will eventually halt when run with that input. In this abstract framework, there are no resource limitations on the amount of memory or time required for the program’s execution; it can take arbitrarily long, and use arbitrarily as much storage space, before halting. The question is simply whether the given program will ever halt on a particular input.

停机问题是用于判断这个程序是否会自动退出或者会一直运行下去。例如一个死循环,在内存没有限制的条件下,这个程序不能自动退出,即它会一直运行下去。对于普通正常的程序,举一个非常简单的例子,如helloworld,在运行结束后会自动退出。你会发现, 这是一个很值得研究的问题。因为计算机的资源是有限的,如果一个程序不会自动停止,它便会消耗大量资源与时间,大大降低了效率。假如我们能够设计一个范型算法,适用于对所有程序进行测试,对不能自动退出的程序发出警告,那么这便会大大提高我们的工作效率。可惜的是,目前并不存在这种算法。

Alan Turing proved in 1936 that a general algorithm to solve the halting problem for all possible program-input pairs cannot exist. A key part of the proof was a mathematical definition of a computer and program, which became known as a Turing machine; the halting problem is undecidable over Turing machines. It is one of the first examples of a decision problem.

对于这个问题,图灵本人便做过验证,发现并不存在一种通用的算法能实现这一功能,他认为这是图灵机上仍不能解决的一个问题,同时他也给出了证明:Halting_problem-Sketch_of_proof

更多的细节详见:Halting problem

那么,我们能不能通过一些条件限制,如时间限制,内存限制来大约估计程序是否会停机?

显然是可以的。虽然停机问题是无法解决的,但是我们可以通过条件限制,即根据它的趋势来预测是否会出现停机,以达到我们测试的目的。

下面我通过讲解一道例题,帮助读者进一步了解停机问题!

2.Example

In this project, the rule is:
TIME LIMIT: 1 second
MEMORY LIMIT: 8 MB
FUNCTION INPUT: 5

What should you do in this project:
1. Define the function “Decide()”;
2. In “Decide()”, different functions will be as input;
3. The program you write should stop the unstopable function;
4. The program you write should run through the stopable function;

Simple understanding of “halt problem”:
Can a program know whether itself can be stop? It just like the “Barber paradox”.

题目已给出main.cpp 与 function.h

// main.cpp
#include <iostream>
#include "Decide.h"
using namespace std;

// time_1 record the time of beginning
// time_2 record the time of ending 
static time_t time_1, time_2;

// Time limit: 1 second
// Memory limit: 8 M
int main() {
    int n;
    time_1 = getCurrentTime(); // define in function.h
    while (cin >> n && n != -1 /* 1 */) {
        switch (n) {
            case 0:
            Decide(display, 1, 1); // test display()
            break;
            case 1:
            Decide(add, 1, 1); // test add()
            break;
            case 2:
            Decide(inf, 1, 1); // test inf()
            break;
            case 3:
            Decide(find, 1, 1); // test find()
            break;
            case 4:
            Decide(alloc, 1, 1); // test alloc()
            break;
            default:
            cout << "Wrong number.\n";
        }
    }
    time_2 = getCurrentTime();
    if (time_2 - time_1 > 1000) // get the time of while and judge whether it exceed 1s
        cout << "Exceed time (1 second).\n";
    else cout << "Finish all function in 1 second.\n";
    return 0;
}

// function.h
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <sys/time.h>
#include <vector>
using namespace std;

// 8M = 8*1024*1024, here "50" may have other function
// it may be different in different situation
static long long int maxMem = 8 * 1024 * 1024 - 50; // 8M
static time_t time_begin, time_now;
static vector<long long int> v;

// check is the type of function pointer that bool()
// func is the type of function pointer that void(check, int, int) 
typedef bool (*check) ();
typedef void (*func) (check, int, int);

long getCurrentTime() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
// tv.tv_sec * 1000 + tv.tv_usec / 1000 transform seconds into millisecond

#define TIC() time_begin = getCurrentTime();
#define TOC() time_now = getCurrentTime();
#define MEM_CHECK() (v.size()*sizeof(long long int) > maxMem ? 1 : 0) // calculate the storage that vector takes

void display(check c, int a, int b) {
    cout << "Input is " << a << " and " << b << ".\n";
}

void add(check c, int a, int b) {
    cout << a << " + " << b << " = " << a + b << ".\n";
}

// Infinite loop inside.
void inf(check c, int a, int b) {
    TIC();
    while (1) {
        TOC();
        // if the time is enough, c() will return true
        // That means the function may run forever
        if (c()) {
            cout << "Infinite break.\n";
            time_now = time_begin = 0;
            break;
        }
    }
}

// Find prime number.
void find(check c, int a, int b) {
    int pos = 1, num = 3;
    TIC();
    while (1) {
        for (int i = 2; i < num; i++)
            if (num % i == 0) break;
            else if (i == num - 1) pos++;
        TOC();
        if (c()) {
            if (num > 20000) cout << "Find succeed!\n";
            else cout << "Find nothing.\n";
            time_now = time_begin = 0;
            break;
        }
        num++; // increase everytime the loop finish
    }
}

// Allocate memory for the program.
void alloc(check c, int a, int b) {
    while (1) {
        long long int ch = 999999999;
        v.push_back(ch);
    // if the memory is enough, c() will return true
    // That means the function may be run forever
        if (c()) {
            if (MEM_CHECK()) cout << "Memory has been full.\n";
            else cout << "Memory hasn't been full.\n";
            v.clear();
            break;
        }
    }
}

其实题目便是要求我们设计出decide()函数以实现对function.h中的函数的测试。测试的标准便是函数运行的时间是否会超出我们预先规定的时间与内存大小。

对于main.cpp 与 function.h 的解析,我都以注释的形式标注在代码旁边。

decide()设计如下:

#include <iostream>
#include "function.h"
using namespace std;

bool breakLoop() {
    if ((time_now - time_begin > 180) ||  // maxTime:1 second
        v.size()*sizeof(long long int) > 8 * 1024 * 1024 - 50)  // maxMemory:8 M
        return true;
    return false;
}

void Decide(func f, int a, int b) { f(breakLoop, a, b); }

这里需要解释的便是180了,其实180 = 200 -20,这里的20跟前面所讲的50的道理是一样的。即这20ms可能会因代码运行的环境不同而不同。我认为,这20s应该是分配给代码中其他组分的时间。对于200,由题意可知,输入最多为5个,假如五个输入对应的都是带有死循环的函数,而整个程序的时间限制为1s, 那么每个输入的最大的时间限制便是1s/5 = 1000ms/5 = 200ms.

3.Conclusion

停机问题是一个很有趣的问题,有兴趣的同学可以进一步地学习。

链接:
Halting problem
如何通俗地解释停机问题(Halting Problem)?


以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!


版权声明:本文为博主原创文章,未经博主允许不得转载。

图灵停机问题(The Halting Problem)

不存在这样一个程序(算法),它能够计算任何程序(算法)在给定输入上是否会结束(停机)。 那么,如何来证明这个停机问题呢? 反证!假设我们某一天真做出了这么一个极度聪明的万能算法(就叫God...
  • niushuai666
  • niushuai666
  • 2012年02月15日 13:45
  • 16485

停机问题--The Halting Problem

http://www.juniata.edu/faculty/rhodes/intro/theory2.htm 看停机问题时,觉得它跟我国的“以子之矛攻子之盾”的想法很相似 ...
  • adream307
  • adream307
  • 2011年05月29日 15:21
  • 1899

图灵停机问题(halting problem)

问题描述 是否存在一个过程能做这件事:该过程以一个计算机程序以及该程序的一个输入作为输入,并判断该过程在给定输入运行时是否最终能停止。 问题解答 1936年图灵证明这样的过程是不存在的。 证明 ...
  • MyLinChi
  • MyLinChi
  • 2018年01月12日 15:00
  • 57

Halting problem(停机问题)

1.Introduction In computability theory, the halting problem is the problem of determining, from a ...
  • linwh8
  • linwh8
  • 2016年06月02日 00:40
  • 959

HomeWork——Halt Problem

初次接触halt problem,wiki百科和google了一下,大概讲的是对于某个程序P,给出某种输入I,求解此程序P是否会达到终止状态。更通俗的说,一个程序说:“我能预测别的程序是否能够brea...
  • jimmy_curry
  • jimmy_curry
  • 2016年05月30日 10:44
  • 201

停机问题的定义和证明

停机问题停机问题(halting problem)是目前逻辑数学的焦点,和第三次数学危机的解决方案。其本质问题是: 给定一个图灵机 T,和一个任意语言集合 S, 是否 T 会最终停机于每一个。其意义相...
  • NGram
  • NGram
  • 2008年03月18日 16:23
  • 497

[计算理论] 停机问题不可解决的简单证明 halting problem

编程问题的提出 我们是否可以编写一个程序用来测试任何可以用哥德尔数表示的程序是否会终止? 反证法 假设这样的测试程序存在,然后证明它的存在将会产生一个矛盾。 证明步骤第一步 假设测试程序存在 ...
  • u014786849
  • u014786849
  • 2015年08月19日 20:30
  • 1007

SVN Problem

http://stackoverflow.com/questions/35962861/how-to-fix-unable-to-create-pristine-install-stream 1、...
  • NRlovestudy
  • NRlovestudy
  • 2016年08月19日 16:37
  • 875

虚拟机类加载机制

摘自《深入理解 Java 虚拟机:JVM 高级特性与最佳实践》(第二版)         虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直...
  • u013678930
  • u013678930
  • 2016年07月20日 11:43
  • 632

图灵停机问题(The Halting Problem)

不存在这样一个程序(算法),它能够计算任何程序(算法)在给定输入上是否会结束(停机)。 那么,如何来证明这个停机问题呢? 反证!假设我们某一天真做出了这么一个极度聪明的万能算法(就叫God...
  • bat67
  • bat67
  • 2016年08月03日 17:56
  • 288
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Halting problem(停机问题)
举报原因:
原因补充:

(最多只允许输入30个字)