Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
pythonで0を作ってみんなも神になろう
Search
國友大地
September 07, 2023
Programming
3.6k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
pythonで0を作ってみんなも神になろう
pythonで0、自然数、整数、有理数を作り、四則演算を作ります。
國友大地
September 07, 2023
Other Decks in Programming
See All in Programming
【デモ】Kiroで体験する仕様駆動開発|設計からコーディングまでAIと進める開発フロー
cmkudo
0
580
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
990
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
110
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
54
36k
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
160
不幸な GC
chencmd
0
880
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
0
430
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
3
1k
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
130
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
370
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
260
業務時間外もAIに働いてもらう話
colorful12
3
10k
Featured
See All Featured
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
320
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
First, design no harm
axbom
PRO
2
1.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Raft: Consensus for Rubyists
vanstee
141
7.7k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
Making Projects Easy
brettharned
120
6.7k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Transcript
Pythonで0を作ろう
はじめまして! 神です。
はじめまして! 今日は数を作っていきます。 理由は、数を作りたいからです。
ルール • Pythonを使う • int, float型とfor文禁止(ただし、一部省略記法としてintを使います) • 有理数の四則演算まで作る
0を作りたい 材料がない!
0を作ろう 世界にまだ何も存在していないので、0を作る材料がありません。 しかしこの世界には「材料がない」という唯一の材料があるのでこれを使います zero = []
1を作ろう この世界には「材料がない」という唯一の材料がありますが使ってしまいました しかしご安心を。この世界には今、材料が生まれました! それを使いましょう! zero = [] one = [zero]
# = [[]]
2を作ろう 2はどうしましょうか。 two = [one]としてもいいし、two = [zero, zero]としてもいいです。 ただ、今回はこうします。 zero
= [] one = [zero] # = [[]] two = [zero, one] # = [[], [[]]]
自然数を作ろう 実は two + [two] = [zero, one] + [two]
= [zero, one, two] = threeとなります。 以降はそうやって自然数を作りましょう。 zero = [] one = [zero] # = [[]] two = [zero, one] # = [[], [[]]] three = two + [two] # = [zero, one, two] ※0は大学数学においては自然数に含む
1を足す関数を作ろう さっき言ったようにこうやって x + 1を計算できます。 # 1を足す関数 後者関数 successor function
def suc(x: Natural) -> Natural: """ x + 1 を計算する""" return x + [x] ※Natural型 = list型
1を引く関数を作ろう 1を引く関数はリストの一番最後を消せばいいのでこうすればいいです。 int型の「-1」を使ってますが、pop()を使えばいいので省略記法として使います。 def pre(x: Natural) -> Natural: """ x
- 1 を計算する x=0ならエラー""" return x[:-1] 今できること • 1を足す
大小関係を作ろう なんと大小関係が1行で判定できる。最高! def is_bigger(x: Natural, y: Natural) -> bool: """
x < y かを判定する""" return x in y 今できること • 1を足す • 1を引く
足し算を作ろう 1を足すことと1を引くことしかできず、for文も禁止なので再帰で書きます。 x + 0 = x、x+y = (x+1)+(y-1)。それはそう。 def
plus(x: Natural, y: Natural) -> Natural: if y == zero: return x # x + 0 = x else: return plus(suc(x), pre(y)) # x+y = (x+1)+(y-1) 今できること • 1を足す • 1を引く • 大小関係
掛け算を作ろう 足し算を繰り返して再帰で書きます。 x * 0 = 0、x * y =
x * (y-1) + x。それはそう。 def mul(x: Natural, y: Natural) -> Natural: if y == zero: return zero # x * 0 = 0 else: # x * y = x * (y-1) + x return plus(mul(x, pre(y)), x) 今できること • 1を足す • 1を引く • 大小関係 • 足し算
掛け算まで作れた やったー!! 今できること • 1を足す • 1を引く • 大小関係 •
足し算 • 掛け算
引き算を作りたい 引き算を「1を引く」の再帰で作ると答えが負のときに困るので、 やりたくないです。 どうにかして x - y = z を今できることで表現できないでしょうか…?
今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 x - y = z
引き算を作りたい 引き算を「1を引く」の再帰で作ると答えが負のときに困るので、 やりたくないです。 どうにかして x - y = z を今できることで表現できないでしょうか…?
今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 x - y = z x = z + y ←!!!!!!
整数を作ろう a - b = c - d の時、 a
+ d = c + b です。 整数を自然数の2つ組で表現しましょう! 自然数a,bを使って整数 a-bを(a, b)と表現します! (1,4) = -3 , (0,0) = 0, (20, 21) = -1, (0,3) = -3 です! Integer = tuple[Natural, Natural] 今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 ※int型とInteger型は異なる
整数を作ろう a - b = c - d の時、 a
+ d = c + b です。 整数を自然数の2つ組で表現しましょう! 自然数a,bを使って整数 a-bを(a, b)と表現します! (1,4) = -3 , (0,0) = 0, (20, 21) = -1, (0,3) = -3 です! (1,4) = (0,3) になってるけど大丈夫? Integer = tuple[Natural, Natural] 今できること • 1を足す • 1を引く • 大小関係 • 足し算 • 掛け算 ※int型とInteger型は異なる
整数の「=」を作ろう 整数が等しいかを判定するためにInteger型の「=」を作る。 a-b = c-d なら a+d = b+c なので簡単
x[0]やx[1]はNatural型なので足し算できる! def eq_i(x: Integer, y: Integer) -> bool: """x[0] - x[1] == y[0] - y[1] かを判定する""" return plus(x[0], y[1]) == plus(y[0], x[1]) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 ※Integerを型ではなくクラスで表現すれば添字 [0][1]は使わずに済むので、ここでの int型0,1は許容
整数の足し算を作ろう (a-b) + (c-d) = (a+c) - (b+d)なので自然数の足し算だけで作れる! def plus_i(x:
Integer, y: Integer) -> Integer: """ x+y を計算する""" # a-b + c-d = (a+c) - (b+d) return (plus(x[0], y[0]), plus(x[1], y[1])) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」
整数の単項マイナスを作ろう a-b = b-aなのでそのまま def neg_i(x: Integer) -> Integer: """
-x を計算する""" return (x[1], x[0]) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算
整数の引き算を作ろう x - y = x + (-y)より作れる。 def minus_i(x:
Integer, y: Integer) -> Integer: """ x-y を計算する""" return plus_i(x, neg_i(y)) # x-y = x + (-y) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転
整数の掛け算を作ろう テキトーにやれば面倒だが出来る。 (a-b)*(c-d)=(a*c-b*c) - (a*c - b*d) def mul_i(x: Integer,
y: Integer) -> Integer: x_mul_y0: Integer = (mul(x[0],y[0]), mul(x[1],y[0])) x_mul_y1: Integer = (mul(x[0],y[1]), mul(x[1],y[1])) return minus_i(x_mul_y0, x_mul_y1) 今できること • 自然数 ◦ 1を足す ◦ 1を引く ◦ 大小関係 ◦ 足し算 ◦ 掛け算 • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算
整数と引き算が作れた 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転
◦ 引き算 ◦ 掛け算 もう自然数は整数の下位互換なので要りません やったー!!
割り算を作りたい x / y = z ↑ これを足し算引き算掛け算だけで表現できないか 今できること •
整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算
割り算を作りたい x / y = z x = z *
y 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 ←!!!!!!
有理数を作ろう なんと!有理数は2つの整数から作ることが出来ます!知ってた。 有理数 x / y を(x, y) と表します! Rational
= tuple[Integer, Integer] 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算
有理数の「=」を作ろう a / b = c / d ならば a
* d = c * bなのでこうなります。 def eq_r(x: Rational, y: Rational) -> bool: return eq_i( mul_i(x[0], y[1]), mul_i(x[1], x[0]) ) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算
有理数の掛け算を作ろう 有理数はみなさん御存知の通り掛け算が一番楽なので作ります。 (a / b) * (c / d) =
(a*c) / (b*d) def mul_r(x: Rational, y: Rational) -> Rational: """ x*y を計算する""" return (mul_i(x[0], y[0]), mul_i(x[1], y[1])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」
有理数の割り算を作ろう 有理数はみなさん御存知の通り割り算が二番楽(?)なので作ります。 (a / b) / (c / d) =
(a*d) / (b*c) def div_r(x: Rational, y: Rational) -> Rational: """ x/y を計算する""" return (mul_i(x[0], y[1]), mul_i(x[1], y[0])) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算
有理数の単項マイナスを作ろう 分数をマイナスにするのは分子にマイナスつけるだけです。 def neg_r(x: Rational) -> Rational: """ -x を計算する"""
return (neg_i(x[0]), x[1]) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算
有理数の足し算を作ろう なんかごちゃごちゃ計算したらできます。 読まなくていいです。 def plus_r(x: Rational, y: Rational) -> Rational:
numerator = plus_i(mul_i(x[0], y[1]), mul_i(x[1], y[0])) denominator = mul_i(x[1], y[1]) return (numerator, denominator) 今できること • 整数 ◦ 「=」 ◦ 足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転
有理数の引き算を作ろう なんかごちゃごちゃ計算したらできます2。 読まなくていいです2。 …と思いきや足し算と単項マイナスがあるので楽です。 今できること • 整数 ◦ 「=」 ◦
足し算 ◦ 正負逆転 ◦ 引き算 ◦ 掛け算 • 有理数 ◦ 「=」 ◦ 掛け算 ◦ 割り算 ◦ 正負逆転 ◦ 足し算 def minus_r(x: Rational, y: Rational) -> Rational: """ x-y を計算する""" return plus_r(x, neg_r(y))
有理数と割り算が作れた もう整数は有理数の下位互換なので要りません やったー!! 今できること • 有理数 ◦ 「=」 ◦ 掛け算
◦ 割り算 ◦ 正負逆転 ◦ 足し算 ◦ 引き算
結論:四則演算がリストから作れた! 今回の数や演算の作り方は、数学における数の作り方の内、 もっともメジャーなもの(ZFC)とほぼ同じです。 数学に「リスト」という構造は、0や1がないと作れない(はず…) ので、 本来は集合をつかって定義されます! なお有理数をさらに進めた実数については、 デデキントカットか無限数列の極限で定義されますが、 どちらも有理数を無限個使うのでコンピュータじゃ無理です。 というか現実では不可能。
うれしい! 満足したので帰ります。
参考資料 元ネタ https://www.nicovideo.jp/watch/sm32548726 琴葉姉妹の数学キソ論:第1回「1+1=2を証明して?」 ↑全人類見ろ https://qiita.com/taketo1024/items/2ab856d21bf9b9f30357 「Swiftで自然数を作ってみた(ペアノの公理)」 他、https://qiita.com/search?q=自然数を作る 内の記事
Qiitaの「数字を作る」系の記事、 だいたい足し算・掛け算までしかやらないがちなのでこのLT作った