エレファント・コンピューティング調査報告

極限に関する順序を論理プログラミングの手法を使って指定することを目指すブロクです。

関数プログラミングと無限論理多項式(2)

今回は3の平方根を1桁ずつ計算するC#の例をJavaScriptで書き直したものを考えます。

JavaScript の例

以下のコードのクラス Numbers の関数 GetNextDecimalDigit() で1桁分の処理を行っています。LongDecimal は小数点以下の任意の桁数を計算することができるクラスとします。

class Numbers {
    constructor(number, square_difference, scale) {
        this.number = number;
        this.square_difference = square_difference;
        this.scale = scale;
        this.current_digit = 0;
    }
    get CurrentDigit() {
        return this.current_digit;
    }
    GetNextDecimalDigit() {
        var two = new LongDecimal(2);
        for (var dd = 9; dd >= 0; dd--) {
            var zd = new LongDecimal(dd, this.scale);
            var number_sq_diff = this.number.Product(zd).Product(two).Sum(zd.Product(zd));
            if (number_sq_diff.LessOrEqual(this.square_difference)) {
                this.number = this.number.Add(dd, this.scale);
                this.square_difference = this.square_difference.Difference(number_sq_diff);
                this.scale++;
                this.current_digit = dd;
                return dd;
            }
        }
        return 0;
    }
}

サーバーで無限に計算するバージョン

サーバーで無限に計算していてブラウザーで1桁ずつ取り出す場合を考えます。サーバーは無限に状態が変化していくもので、それをクラスで表しています。ここでは以下のようにJavaScriptイテレーターを使ったクラスとしています。GenerateDecimal() がジェネレーターとなっています。

class NumbersGenerator {
    GetNextDecimalDigit() {
        return generator_gen.next().value;
    }
    *GenerateDecimal() {
        var number = new LongDecimal();
        var square_difference = new LongDecimal(3);
        var nums = new Numbers(number, square_difference, 0);
        for (; ;) {
            yield nums.GetNextDecimalDigit();
        }
    }
}

JavaScriptの仕様は複雑なのでよくわからないのですが、クラスのメンバーにジェネレーターを保持することはできないようで、ここではクラスの外部に generator_gen を定義して、これをクラスの内部で参照するようになっています。クラスのインスタンスは1個しかないので、これでも動作します。generator はサーバーを表すクラスです。これらは以下のように定義されます。

var generator;
generator = new NumbersGenerator();

var generator_gen;
generator_gen = generator.GenerateDecimal();
サーバーから1回ずつ値を取り出す方法

以下の関数を呼び出すと、result_number に1桁ずつ結果が追加され、その結果の文字列を返します。

function NextDecimalByGenerator() {
    result_number.AddLast(generator.GetNextDecimalDigit());
    return result_number.Print();
}

result_number は以下のように定義されます。

var result_number;
result_number = new LongDecimal();
イテレーターを直接使う方法

以下の関数の generator.GenerateDecimal() はジェネレーターで Take はその最初の部分を取り出す、Haskell の take と同様の関数を定義したものとなります。この関数を呼び出すと、呼び出した回数分の結果の文字列を返します。

function NextDecimalByGeneratorTake() {
    var res = new LongDecimal(Take(scale, generator.GenerateDecimal())).Print();
    scale++;
    return res;
}

scale は以下のように定義されます。

var scale;
scale = 0;

ブラウザーで計算するバージョン

サーバーにデータがあってそれをブラウザーで取り出して1桁ずつ計算する場合を考えます。ここでも(サーバーから1回ずつ値を取り出す場合は)クラスで表しています。以下のようにJavaScriptイテレーターを使ったクラスとしています。JavaScriptではイテレーターの実行中に値を返すことができます。GenerateDecimalServer() のイテレーターのループ内の current_numbers で受け取っています。

class NumbersServer {
    GetNumbers(numbers) {
        var current = generator_server_gen.next(numbers);
        return current.value;
    }
    SetNumbers(numbers) {
        this.current_numbers = numbers;
    }
    *GenerateDecimalServer() {
        var number = new LongDecimal();
        var square_difference = new LongDecimal(3);
        var current_numbers = new Numbers(number, square_difference, 0);
        for (; ;) {
            current_numbers = yield current_numbers;
        }
    }
}

ここでもクラスの外部に generator_server_genを定義して、これをクラスの内部で参照するようになっています。generator_server はサーバーを表すクラスです。これらは以下のように定義されます。

var generator_server;
generator_server = new NumbersServer();

var generator_server_gen;
generator_server_gen = generator_server.GenerateDecimalServer();
サーバーから1回ずつ値を取り出す方法

以下の関数を呼び出すと、result_number に1桁ずつ結果が追加され、その結果の文字列を返します。

var current_numbers = null;
function NextDecimalByServer() {
    current_numbers = generator_server.GetNumbers(current_numbers);
    var dd = current_numbers.GetNextDecimalDigit();
    generator_server.SetNumbers(current_numbers);
    result_number.AddLast(dd);
    return result_number.Print();
}

result_number は以下のように定義されます。

var result_number;
result_number = new LongDecimal();
Iterate 関数を使う方法

イテレーターを直接使うとイテレーターに値を返す方法がないので「サーバーで無限に計算するバージョン」のような「イテレーターを直接使う方法」はできません。ここではサーバーのクラスを使わずに、Haskell の iterate と同様の関数 Iterate を定義して使います。Iterate は指定された初期値から指定された関数を繰り返して適用した無限の列を返すもので、Iterate で生成されるものがジェネレーターで生成されるものと同様のものとなります。Map_ は Haskell の map に相当するものを定義しています。JavaScript にも map はあるのですが、使い方がよくわからないので使っていません。この関数を呼び出すと、呼び出した回数分の結果の文字列を返します。

function NextDecimalByServerTake() {
    var number = new LongDecimal();
    var square_difference = new LongDecimal(3);
    var init_numbers = new Numbers(number, square_difference, 0);
    init_numbers.GetNextDecimalDigit();
    var res = new LongDecimal(Map_(numbers => numbers.CurrentDigit, Take(scale, Iterate(NextNumbers, init_numbers)))).Print();
    scale++;
    return res;
}

scale は以下のように定義されます。

var scale;
scale = 0;

関数プログラミングと無限論理多項式(1)

この記事では、サーバーで無限に実行されるプログラムとブラウザーで実行されるプログラムを組み合わせたものを記述する方法について考えていきます。まずC#イテレーターで考えてみます。今後はHaskellなどのプログラミング言語とも比較していきたいと思います。

C# の例

例として3の平方根を1桁ずつ計算することを考えます。

 r_0 = 0 (コードでは number)、 q_0 = 3 (コードでは square_difference)とします。 e = 0, 1, \cdots (コードでは scale)に対して  r_e (コードでは number)、 q_e (コードでは square_difference)、 d_e \in D = \{0, 1, \cdots, 9\} (コードでは dd)を以下のように決めます。

 r_{e+1} = r_e + 10^{-e} d_e q_e = q_0 - r_e^2 q_{e+1} = q_0 - r_{e+1}^2 h_e = r_{e+1}^2 - r_e^2 = q_e - q_{e+1} = r_e \cdot 10^{-e} d \cdot 2 + 10^{-2e} d^2 としたとき  d_e = \max\{ d_e \in D \mid r_{e+1}^2 \le q_0 \} = \max\{ d_e \in D \mid h_e \le q_e \} とします。

以下のコードのクラス Numbers の関数 GetNextDecimalDigit() でこの1桁分の処理を行っています。LongDecimal は小数点以下の任意の桁数を計算することができるクラスとします。

    internal class Numbers
    {
        private LongDecimal number;
        private LongDecimal square_difference;
        private int scale;
        private int current_digit = 0;
        public Numbers(LongDecimal number, LongDecimal square_difference, int scale)
        {
            this.number = number;
            this.square_difference = square_difference;
            this.scale = scale;
        }
        public int CurrentDigit
        {
            get { return current_digit; }
        }
        public int GetNextDecimalDigit()
        {
            LongDecimal two = new LongDecimal(2);
            for (int dd = 9; dd >= 0; dd--)
            {
                LongDecimal zd = new LongDecimal(dd, scale);
                LongDecimal number_sq_diff = number * zd * two + zd * zd;
                if (number_sq_diff <= square_difference)
                {
                    number = number.Add(dd, scale);
                    square_difference -= number_sq_diff;
                    scale++;
                    current_digit = dd;
                    return dd;
                }
            }
            return 0;
        }
    }

サーバーで無限に計算するバージョン

サーバーで無限に計算していてブラウザーで1桁ずつ取り出す場合を考えます。サーバーは無限に状態が変化していくもので、それをクラスで表しています。ここでは以下のようにC#イテレーターを使ったクラスとしています。GenerateDecimal() がジェネレーターとなっています。

    internal class NumbersGenerator
    {
        public NumbersGenerator()
        {
            generator = GenerateDecimal().GetEnumerator();
        }
        private IEnumerator<int> generator;
        public int GetNextDecimalDigit()
        {
            generator.MoveNext();
            return generator.Current;
        }
        public IEnumerable<int> GenerateDecimal()
        {
            LongDecimal number = new LongDecimal();
            LongDecimal square_difference = new LongDecimal(3);
            Numbers nums = new Numbers(number, square_difference, 0);
            for(; ;)
            {
                yield return nums.GetNextDecimalDigit();
            }
        }
    }
サーバーから1回ずつ値を取り出す方法

以下の関数を呼び出すと、result_number に1桁ずつ結果が追加され、その結果の文字列を返します。

        private string NextDecimalByGenerator()
        {
            result_number.AddLast(generator.GetNextDecimalDigit());
            return result_number.Print();
        }

ここで generator はサーバーを表すクラスです。これらは以下のように定義されます。

        private NumbersGenerator generator;
        generator = new NumbersGenerator();

        private LongDecimal result_number;
        result_number = new LongDecimal();
イテレーターを直接使う方法

以下の関数の generator.GenerateDecimal() はジェネレーターで Take はその最初の部分を取り出すもの(C#の拡張メソッド)となります。この関数を呼び出すと、呼び出した回数分の結果の文字列を返します。

        private string NextDecimalByGeneratorTake()
        {
            string res = new LongDecimal(generator.GenerateDecimal().Take(scale + 1)).Print();
            scale++;
            return res;
        }

generator、scale は以下のように定義されます。

        private NumbersGenerator generator;
        generator = new NumbersGenerator();

        private int scale;
        scale = 0;

ブラウザーで計算するバージョン

サーバーにデータがあってそれをブラウザーで取り出して1桁ずつ計算する場合を考えます。ここでも(サーバーから1回ずつ値を取り出す場合は)クラスで表しています。以下のようにC#イテレーターを使ったクラスとしています。C#ではイテレーターの実行中に値を返す方法がないので、クラスのメンバーとして返すようになっています(Numbers プロパティ)。この Numbers プロパティを GenerateDecimalServer() のイテレーターのループ内で参照しています。

    internal class NumbersServer
    {
        public NumbersServer()
        {
            generator_server = GenerateDecimalServer().GetEnumerator();
        }
        private IEnumerator<Numbers> generator_server;
        private Numbers current_numbers;
        private Numbers GetNumbers()
        {
            generator_server.MoveNext();
            return generator_server.Current;
        }
        private void SetNumbers(Numbers numbers)
        {
            current_numbers = numbers;
        }
        public Numbers Numbers
        {
            get
            {
                return GetNumbers();
            }
            set
            {
                SetNumbers(value);
            }
        }
        public IEnumerable<Numbers> GenerateDecimalServer()
        {
            LongDecimal number = new LongDecimal();
            LongDecimal square_difference = new LongDecimal(3);
            current_numbers = new Numbers(number, square_difference, 0);
            for (; ; )
            {
                yield return current_numbers;
            }
        }
    }
サーバーから1回ずつ値を取り出す方法

以下の関数を呼び出すと、result_number に1桁ずつ結果が追加され、その結果の文字列を返します。

        private string NextDecimalByServer()
        {
            Numbers numbers = generator_server.Numbers;
            int dd = numbers.GetNextDecimalDigit();
            generator_server.Numbers = numbers;
            result_number.AddLast(dd);
            return result_number.Print();
        }

ここで generator_server はサーバーを表すクラスです。これらは以下のように定義されます。

        private NumbersServer generator_server;
        generator_server = new NumbersServer();

        private LongDecimal result_number;
        result_number = new LongDecimal();
Iterate 関数を使う方法

イテレーターを直接使うとイテレーターに値を返す方法がないので「サーバーで無限に計算するバージョン」のような「イテレーターを直接使う方法」はできません。ここではサーバーのクラスを使わずに、Haskell の iterate と同様の関数 Iterate を定義して使います。Iterate は指定された初期値から指定された関数を繰り返して適用した無限の列を返すもので、Iterate で生成されるものがジェネレーターで生成されるものと同様のものとなります。Select は Haskell の map に相当するもの(C#の拡張メソッド)となります。この関数を呼び出すと、呼び出した回数分の結果の文字列を返します。

        private string NextDecimalByServerTake()
        {
            LongDecimal number = new LongDecimal();
            LongDecimal square_difference = new LongDecimal(3);
            Numbers init_numbers = new Numbers(number, square_difference, 0);
            init_numbers.GetNextDecimalDigit();
            string res = new LongDecimal(Iterate(NextNumbers, init_numbers).Take(scale + 1).Select(numbers => numbers.CurrentDigit)).Print();
            scale++;
            return res;
        }

scale は以下のように定義されます。

        private int scale;
        scale = 0;

小数点以下20桁を計算した結果は以下のようになります。
1.73205080756887729352

今後はこれらを統一して記述する方法を考えていきます。

現状報告(3)

Coq/SSReflect/MathCompによる定理証明:フリーソフトではじめる数学の形式化という本のKindle版がなかったのでKinoppyで購入。Kinoppyは初めて使いました。PCでは字が小さくて読みにくいですがiPadの大きいのを持っているのでそっちではなんとか読めます。PC版はなんとかしてほしいです。

定理証明手習いという本もKindle版がなかったのでラムダノートのサイトから電子書籍を購入。これはPDFなので拡大すれば読めます。iPadでもなんとか読めます。

Kindle版があれば片手で持てるのでそっちの方が便利ですが、文字のサイズが固定されているものは読めないのでこれらの本に関しては同じかと思います。

現状報告(2)

TeXからはてなブログに変換するツールを作ろうと思って、Visual StudioPythonが使えるようなのでやってみましたが、正規表現のやり方が普通と違う感じになってしまいました。たぶん普通のやり方でもできるとは思うのですが、Pythonはよく知らないのでわかりませんでした。C#でやればたぶんすぐできるんですけど、今後のことを考えてPythonも使えるようにしたいと思ったのですが。

そこでPerlでやってみようと思って、Strawberry Perlをインストールしたのですが、Visual Studio Code拡張機能が何を使えば良いのかウェブで見た限りではよくわかりませんでした。Strawberry Perlに開発環境のようなものがあってそれを使えば良いのかと思うのですが、Visual Studio Codeの設定を自分でやったことがないので今のところはできません。

そこでGoをインストールしてみました。これはVisual Studio Code拡張機能のやり方がウェブに書いてあったし、正規表現C#Perlと同じような感じでできました。

Haskellも開発環境のようなものがあって、それをVisual Studio Codeから使う方法がウェブに書いてあったのでいつかやってみたいと想います。

現状報告(1)

Windows10のノートPCを使っていたのですが、変な音がするようになったので、新しくWindows11のノートPCを購入しました。そのPCでこのブログを書いていたら、「デバイスに問題が発生したため、再起動する必要があります。エラー情報を収集しています。自動的に再起動します。」という水色の画面になる現象が頻繁に発生するようになったため、このブログはなかなか更新できません。この画面がでると自動的に再起動されてしまいます。

「BlueScreenView」で調べるとその時は「ntoskrnl.exe」で発生しているらしいとうことはわかりましたが、対処法はわかりませんでした。その時は「IRQL_NOT_LESS_OR_EQUAL」というのが出ていたのを見たのですが「DRIVER_IRQL_NOT_LESS_OR_EQUAL」、「KMODE_EXCEPTION_NOT_HANDLED」というコードのこともあるようです。「KMODE_EXCEPTION_NOT_HANDLED」のときは「ntoskrnl.exe」の他に「storport.sys」も表示されていました。

ブログを書いているとき以外でも、Twitterを見ているときなどに発生することがあるので、何が原因なのかよくわかりません。発生する前にブログを書いていたような気もするのですがはっきりした記憶はありません。ブログを書くときやTwitterを見るときはChromeを使っているし、Bluetoothのマウスとキーボードを使っているし、ウイルスバスタークラウドも使っているのでそれが原因かもしれないし、この現象が発生するようになる前にもいろいろインストールしたのでそれが原因かもしれないし、使っていないので関係ないかもしれません。

その後、Visual Studio CodeTeXが使えるようにインストールして使っていたら、その時も頻繁に発生するようになりました。この場合も書いているときだけではなくて、その後にも発生するような気はするのですがはっきりしたことはわかりません。

ABC予想と無限論理多項式(1)

ABC予想(1)

まず「ABC予想 - Wikipedia」に従って定義を述べます。自然数  n に対して、 n の互いに異なる素因数の積を  n の根基 (radical) と呼び、 \operatorname {rad} n と書きます。自然数の組  (a, b, c) で、 a + b = c, a < b で、 a b は互いに素であるものを abc-triple と呼びます。

ABC予想(1) (『日本一わかりやすいABC予想』に合わせて修正)任意の  ε > 0 に対して、次を満たすような abc-triple  (a, b, c) は高々有限個しか存在しない:

  •  c < \operatorname{rad} (abc)^{1+\varepsilon}

ABC予想(2) (ABC予想(1)と同値、Oesterlé–Masser の ABC予想)任意の  ε > 0 に対してある  K(ε) > 0 が存在し、全ての abc-triple  (a, b, c) について次が成り立つ:

  •  c < K(\varepsilon) \cdot \operatorname{rad}(abc)^{1+\varepsilon}

ABC予想がどのようなものなのかは『日本一わかりやすいABC予想』に書かれています。この本ではABC予想(2)がABC予想として書かれていて、ABC予想(1)はABC予想(言い換え)として書かれています。ABC予想(2)で  \varepsilon = 1 K(\varepsilon) = 1 としたものをABC仮予想としています。

ABC仮予想 全ての abc-triple  (a, b, c) について次が成り立つ:

  •  c < \operatorname{rad} (abc)^{2}

ABC仮予想が成り立つとすると、 (a^n, b^n, c^n) を考えることによりフェルマー予想 n \ge 6 の場合が成り立ちます。 n \le 5 の場合はワイルズの証明とは別に証明されているので、ワイルズの証明とは別に証明されたことになります。

ABC予想(2)

ABC予想入門 (PHPサイエンス・ワールド新書)』では、 a, b, c を整数としたABC仮予想に対応するものが書かれています。

abc予想(☆) 互いに素な整数  a, b, c a + b = c を満たすならば

  •  \max\{ |a|, |b|, |c| \} < \operatorname{rad}(abc)^2

が成り立つ。

また、 a, b, c を整数としたABC予想(2)に対応するものが書かれています。

abc予想 任意の  ε > 0 に対してある  K(ε) \ge 1 が存在し、互いに素な整数  a, b, c a + b = c を満たすならば

  •  \max\{ |a|, |b|, |c| \} < K(ε) \cdot \operatorname{rad}(abc)^{1+ε}

が成り立つ。

ABC予想(2)とは記述が少し異なりますが、同じことを主張しているようです。『ABC予想入門 (PHPサイエンス・ワールド新書)』では、整数に関する主張となっています。これは、多項式と整数を対応させているのだと思われるのですが、ABC予想では「多項式版」と「整数版」は直接対応していないようなので、このあたりがどうなっているのかさらに読んでみたいと思います。

また、『ABC予想入門 (PHPサイエンス・ワールド新書)』では、相異なる素数  p_1, p_2, \cdots, p_n の有限個の積全体からなる積に関する可換モノイドを  \mathbb{F}_1[p_1, p_2, \cdots, p_n] と表しています。素因数分解の一意性により、 \mathbb{F}_1[p_1, p_2, \cdots, p_n]単位元をもつ自明ではない可換環上の多項式環  R[x_1, x_2, \cdots, x_n] x_1, x_2, \cdots, x_n で生成される積に関する部分モノイドとモノイドとして同型となります。

素因数分解の一意性とは以下のようなものになります。

 p_1, p_2, \cdots, p_n を相異なる素数とし、 q_1, q_2, \cdots, q_k, r_1, r_2, \cdots, r_l素数とし、 \{p_1, p_2, \cdots, p_n\} = \{q_1, q_2, \cdots, q_k, r_1, r_2, \cdots, r_l\} q_1 q_2 \cdots q_k = r_1 r_2 \cdots r_l とします。 M \{\overline{p_1}, \overline{p_2}, \cdots, \overline{p_n}\} で生成された自由可換モノイドとし、 f: \mathbb{F}_1[p_1, p_2, \cdots, p_n] \to M p_i \overline{p_i} に写すモノイドの準同型とすると、 f(q_1 q_2 \cdots q_k) = f(r_1 r_2 \cdots r_l) となります。

 X を集合とし、 \mathbb{F}_1[X] X で生成される自由可換モノイドを多項式として見たものとします。すると、 P素数全体からなる集合としたとき、 \mathbb{F}_1[P] は正の整数全体からなる可換モノイドを多項式として見たものとなります。

多項式abc予想

ABC予想入門 (PHPサイエンス・ワールド新書)』では、「多項式abc予想」について書かれています。

多項式abc予想(1) (定理 4.1)  a, b, c \in \mathbb{C}[x] \setminus \{0\} を互いに素な多項式で、どれかは定数ではないとします。このとき  a + b = c を満たすならば

  •  \max\{ \deg(a), \deg(b), \deg(c) \} < \deg(\operatorname{rad}(abc))

が成り立ちます。ここで  \operatorname{rad}(abc) は \begin{eqnarray*}
a(x) & = & A \prod_i (x - \alpha_i)^{l_i} \\
b(x) & = & B \prod_j (x - \beta_j)^{m_j} \\
c(x) & =& C \prod_k (x - \gamma_k)^{n_k}
\end{eqnarray*} ( A, B, C は定数、 \alpha_i, \beta_j, \gamma_k は相異なる根、 l_i, m_j, n_k自然数 l_i, m_j, n_k \ge 1) のとき
 \displaystyle \operatorname{rad}(abc) = \prod_i (x - \alpha_i) \prod_j (x - \beta_j) \prod_k (x - \gamma_k)
とします。

この定理は一般の体  F で成り立つと書かれています。 F a, b, c の根をすべて含む場合は同じ証明ができるので、まずその場合の証明を書いてみます(ほとんど定理4.1の証明の引用)。

多項式abc予想(2)  F を体とします。 a, b, c \in F[x] \setminus \{0\} を互いに素な多項式で、 a' = b' = c' = 0 ではないとします。さらに  F a, b, c の根をすべて含むとします。このとき  a + b = c を満たすならば

  •  \max\{ \deg(a), \deg(b), \deg(c) \} < \deg(\operatorname{rad}(abc))

が成り立ちます。

[証明]  a + b = c微分して  a' + b' = c' が成り立ちます。この二つの式より  a \left(\cfrac{c'}{c} - \cfrac{a'}{a}\right) = b \left(\cfrac{b'}{b} - \cfrac{c'}{c}\right) が成り立ちます。

 \displaystyle \cfrac{a'}{a} = \sum_i \cfrac{l_i}{x - \alpha_i} \displaystyle \cfrac{b'}{b} = \sum_j \cfrac{m_j}{x - \beta_j} \displaystyle \cfrac{c'}{c} = \sum_k \cfrac{n_k}{x - \gamma_k} より  \operatorname{rad}(abc) \cfrac{a'}{a} \operatorname{rad}(abc) \cfrac{b'}{b} \operatorname{rad}(abc) \cfrac{c'}{c}多項式となります。

 a \operatorname{rad}(abc) \left(\cfrac{c'}{c} - \cfrac{a'}{a}\right) = b \operatorname{rad}(abc) \left(\cfrac{b'}{b} - \cfrac{c'}{c}\right) であり、 a, b は互いに素なので  a \mid \operatorname{rad}(abc) \left(\cfrac{b'}{b} - \cfrac{c'}{c}\right) となります。次数を比較して  \deg(a) \le \deg(\operatorname{rad}(abc)) - 1 < \deg(\operatorname{rad}(abc)) となります。

同様に  b \mid \operatorname{rad}(abc) \left(\cfrac{c'}{c} - \cfrac{a'}{a}\right) となります。次数を比較して  \deg(b) \le \deg(\operatorname{rad}(abc)) - 1 < \deg(\operatorname{rad}(abc)) となります。

 c = a + b より  \deg(c) \le \{ \deg(a), \deg(b) \} < \deg(\operatorname{rad}(abc)) となります。[証明終わり]

 F に対して、 F a, b, c の根をすべて含む体を考えると以下が成り立ちます。

多項式abc予想(3) (定理 4.3 (A))  F を体とします。 a, b, c \in F[x] \setminus \{0\} を互いに素な多項式で、 a' = b' = c' = 0 ではないとします。このとき  a + b = c を満たすならば

  •  \max\{ \deg(a), \deg(b), \deg(c) \} < \deg(\operatorname{rad}(abc))

が成り立ちます。ただし
 \displaystyle \operatorname{rad}(abc) = \prod_{h \mid abc, h は素元} h

この本ではさらに  a, b, c \in F[x_1, \cdots, x_n] のときを考えてみることが「お勧め」されていますが、これを考えると多項式と整数の対応がわかるのかもしれません。少し読んでみた限りではわからなかったのでもう少し読んでいきたいと思います。