{"id":13632238,"url":"https://github.com/tomstuart/computationbook","last_synced_at":"2025-06-22T21:05:32.243Z","repository":{"id":63723245,"uuid":"10119986","full_name":"tomstuart/computationbook","owner":"tomstuart","description":"Example code for Understanding Computation","archived":false,"fork":false,"pushed_at":"2015-07-06T20:04:52.000Z","size":239,"stargazers_count":500,"open_issues_count":2,"forks_count":99,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-04-18T14:32:10.689Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://computationbook.com/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomstuart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-17T09:16:15.000Z","updated_at":"2025-02-24T05:16:09.000Z","dependencies_parsed_at":"2022-11-24T17:52:09.468Z","dependency_job_id":null,"html_url":"https://github.com/tomstuart/computationbook","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tomstuart/computationbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomstuart%2Fcomputationbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomstuart%2Fcomputationbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomstuart%2Fcomputationbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomstuart%2Fcomputationbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomstuart","download_url":"https://codeload.github.com/tomstuart/computationbook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomstuart%2Fcomputationbook/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261367503,"owners_count":23147851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T22:02:57.173Z","updated_at":"2025-06-22T21:05:27.214Z","avatar_url":"https://github.com/tomstuart.png","language":"Ruby","readme":"Understanding Computation example code\n======================================\n\nThis is the example code for [Understanding Computation](http://computationbook.com/), an O’Reilly book about computation theory. (Here’s [a sample chapter](http://cdn.oreillystatic.com/oreilly/booksamplers/9781449329273_sampler.pdf).) Ruby 1.9 or 2.0 is required.\n\nRight now it’s a pretty rough dump of code from the book. Each chapter has its own directory:\n\n* Chapter 2: [The Meaning of Programs](the_meaning_of_programs)\n    * [syntax](the_meaning_of_programs/syntax)\n    * [parser](the_meaning_of_programs/parser)\n    * [small-step operational semantics](the_meaning_of_programs/small_step)\n    * [big-step operational semantics](the_meaning_of_programs/big_step)\n    * [denotational semantics](the_meaning_of_programs/denotational)\n* Chapter 3: [The Simplest Computers](the_simplest_computers)\n    * [deterministic and nondeterministic finite automata](the_simplest_computers/finite_automata)\n    * [regular expressions](the_simplest_computers/regular_expressions)\n* Chapter 4: [Just Add Power](just_add_power)\n    * [deterministic and nondeterministic pushdown automata](just_add_power)\n* Chapter 5: [The Ultimate Machine](the_ultimate_machine)\n    * [deterministic Turing machines](the_ultimate_machine)\n* Chapter 6: [Programming with Nothing](programming_with_nothing)\n    * [FizzBuzz with procs](programming_with_nothing/fizzbuzz)\n    * [the lambda calculus](programming_with_nothing/lambda_calculus)\n* Chapter 7: [Universality is Everywhere](universality_is_everywhere)\n    * [partial recursive functions](universality_is_everywhere/partial_recursive_functions)\n    * [the SKI combinator calculus](universality_is_everywhere/ski_calculus)\n    * [Iota](universality_is_everywhere/iota)\n    * [tag systems](universality_is_everywhere/tag_systems)\n    * [cyclic tag systems](universality_is_everywhere/cyclic_tag_systems)\n* Chapter 8: [Impossible Programs](impossible_programs)\n* Chapter 9: [Programming in Toyland](programming_in_toyland)\n    * [abstract interpretation: arithmetic with signs](programming_in_toyland/signs)\n    * [type systems](programming_in_toyland/types)\n\nEach directory contains definitions of the classes implemented in that chapter. There’s also a file named after each chapter (e.g. [`just_add_power.rb`](just_add_power.rb)) that can be `require`d to load all the code for that chapter.\n\nFor example:\n\n```irb\n$ irb -I.\n\u003e\u003e require 'universality_is_everywhere'\n=\u003e true\n\u003e\u003e identity = SKICall.new(SKICall.new(S, K), SKICall.new(K, K))\n=\u003e S[K][K[K]]\n\u003e\u003e x = SKISymbol.new(:x)\n=\u003e x\n\u003e\u003e expression = SKICall.new(identity, x)\n=\u003e S[K][K[K]][x]\n\u003e\u003e while expression.reducible?; puts expression; expression = expression.reduce; end; puts expression\nS[K][K[K]][x]\nK[x][K[K][x]]\nK[x][K]\nx\n=\u003e nil\n```\n\nIf you run `bundle install` to install [Treetop](http://treetop.rubyforge.org/), you can try out the parsers:\n\n```irb\n$ bundle exec irb -I.\n\u003e\u003e require 'treetop'\n=\u003e true\n\u003e\u003e Treetop.load('the_meaning_of_programs/parser/simple')\n=\u003e SimpleParser\n\u003e\u003e require 'the_meaning_of_programs'\n=\u003e true\n\u003e\u003e program = SimpleParser.new.parse('while (x \u003c 5) { x = x * 3 }').to_ast\n=\u003e «while (x \u003c 5) { x = x * 3 }»\n\u003e\u003e program.reduce(x: Number.new(3))\n=\u003e [«if (x \u003c 5) { x = x * 3; while (x \u003c 5) { x = x * 3 } } else { do-nothing }», {:x=\u003e«3»}]\n\u003e\u003e program.evaluate(x: Number.new(3))\n=\u003e {:x=\u003e«9»}\n\u003e\u003e program.to_ruby\n=\u003e \"-\u003e e { while (-\u003e e { (-\u003e e { e[:x] }).call(e) \u003c (-\u003e e { 5 }).call(e) }).call(e); e = (-\u003e e { e.merge({ :x =\u003e (-\u003e e { (-\u003e e { e[:x] }).call(e) * (-\u003e e { 3 }).call(e) }).call(e) }) }).call(e); end; e }\"\n\u003e\u003e eval(program.to_ruby).call(x: 3)\n=\u003e {:x=\u003e9}\n```\n\n```irb\n$ bundle exec irb -I.\n\u003e\u003e require 'treetop'\n=\u003e true\n\u003e\u003e Treetop.load('programming_with_nothing/lambda_calculus/lambda_calculus')\n=\u003e LambdaCalculusParser\n\u003e\u003e require 'programming_with_nothing'\n=\u003e true\n\u003e\u003e two = LambdaCalculusParser.new.parse('-\u003e p { -\u003e x { p[p[x]] } }').to_ast\n=\u003e -\u003e p { -\u003e x { p[p[x]] } }\n\u003e\u003e require 'universality_is_everywhere'\n=\u003e true\n\u003e\u003e two.to_ski\n=\u003e S[S[K[S]][S[K[K]][I]]][S[S[K[S]][S[K[K]][I]]][K[I]]]\n\u003e\u003e two.to_ski.to_iota\n=\u003e ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ]]]]][ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ]]]]][ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ]]]]\n\u003e\u003e inc, zero = SKISymbol.new(:inc), SKISymbol.new(:zero)\n=\u003e [inc, zero]\n\u003e\u003e expression = SKICall.new(SKICall.new(two.to_ski.to_iota, inc), zero)\n=\u003e ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ]]]]][ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]]]][ɩ[ɩ[ɩ[ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ[ɩ[ɩ]]]]][ɩ[ɩ]]]][ɩ[ɩ[ɩ[ɩ]]][ɩ[ɩ]]]][inc][zero]\n\u003e\u003e expression = expression.reduce while expression.reducible?\n=\u003e nil\n\u003e\u003e expression\n=\u003e inc[inc[zero]]\n```\n\nIf you have any questions, please get in touch via [Twitter](http://twitter.com/tomstuart) or [email](mailto:tom@codon.com). If you find any bugs or other programs with the code, please [open an issue](https://github.com/tomstuart/computationbook/issues/new).\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomstuart%2Fcomputationbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomstuart%2Fcomputationbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomstuart%2Fcomputationbook/lists"}