{"id":16347999,"url":"https://github.com/ai/evolu-lang","last_synced_at":"2025-09-29T22:31:07.609Z","repository":{"id":1011191,"uuid":"832349","full_name":"ai/evolu-lang","owner":"ai","description":"Programming language to automatically generate programs by evolution (genetic programming).","archived":false,"fork":false,"pushed_at":"2012-03-10T15:14:35.000Z","size":200,"stargazers_count":22,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-13T20:52:11.145Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://ai.github.io/evolu-lang/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"rsc/pdf","license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-08-11T23:29:43.000Z","updated_at":"2021-03-27T17:18:20.000Z","dependencies_parsed_at":"2022-07-06T01:31:18.703Z","dependency_job_id":null,"html_url":"https://github.com/ai/evolu-lang","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fevolu-lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fevolu-lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fevolu-lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fevolu-lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ai","download_url":"https://codeload.github.com/ai/evolu-lang/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234672814,"owners_count":18869554,"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-10-11T00:48:00.428Z","updated_at":"2025-09-29T22:31:02.352Z","avatar_url":"https://github.com/ai.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Evolu Lang\n\nEvolu Lang is a programming language to automatically generate programs by\nevolution (genetic programming). Generator (genetic algorithm, particle swarm\noptimization or other) will use Evolu Lang to compile bytes with random\nmutations (gene) to program, run and test it.\n\nIt is created to be readable by human beings (instead of\nartificial neural networks) and easily editable and mixable for genetic\nalgorithm (instead of tree structure and modern production languages).\n\n## How It Works\n\nA developer defines commands by Evolu Lang to create a business specific\nlanguage (or uses the standard commands pack) and defines tests (*fitness*),\nto determine what program he or she wants to create.\n\nIn the next step he or she uses a generator, which uses a genetic algorithm,\nparticle swarm optimization or other evolutionary algorithms.\nIn the simplest case:\n1. Generator creates an array (*population*) with random bytes (*genes*).\n2. It adds random changes (*mutation*) to each byte stream in this array.\n3. It compiles each of these random byte streams by Evolu Lang and runs\n   obtained programs with tests.\n4. Bad programs will be deleted and best programs will be copied to the\n   population.\n5. Generator returns to step 2 until an obtained program passes all of the\n   tests.\n\n## Features\n\n* It is similar to usual programming languages with variables, commands, blocks\n  and conditions.\n* Simple and explicit code. If you change one byte of code, you will change one\n  command or parameter in program. If you just join two half parts of two\n  different programs, you will get algorithm with properties of both parts.\n* Program is coded to a byte stream, so you can use a lot of libraries to mutate\n  programs. Of course, you can use the string form for debug and research.\n* You are able to extend standard commands and conditions for the purposes of\n  your task.\n* It has an interpreter in JavaScript, so you can create a distributed cluster\n  from site visitors with a simple web page.\n\n## Language Philosophy\n\n* **Explicit code.** To control mutation, we must know, that when we change one\n  byte, the algorithm will change slightly. When we copy a part of one algorithm\n  to another, we expect, that the second algorithm will get some properties from\n  the first one.\n* **Everything makes sense.** A mutation doesn’t know about syntax and formats.\n  Interpreter must try to get maximum sense, from any byte stream. For example,\n  if a byte can code 2 values, we must read even bytes as first value and odd\n  values as second. So any byte value makes sense, not just the first two.\n* **Simple structures.** We can’t demand on the mutation placing all conditions\n  in the beginning of a block. A better way is to mark conditions and expect\n  them in any place of a block.\n\n## Description\n\n### Program\n\nEach Evolu program starts with an `EVOLU:` prefix to check, that the file or\nstream contains a program.\n\nLike XML, Evolu Lang is just a syntax format. So you need to have\nbusiness-specific languages and mark, what language is used in this Evolu\nprogram. So, after the `EVOLU:` prefix, stream must contain language name and a\ncolon.\n\n    \u003cprogram\u003e ::= \"EVOLU:\" \u003clanguage\u003e \":\" \u003crules\u003e\n\nLanguage name is case insensitive and may contain any chars, except colon and\nspace.\n\nThe genetic algorithm shouldn’t change these prefixes, they should be used only\nto store and transfer Evolu programs.\n\n### Rules\n\nAn Evolu program is split to separated blocks, *rules*, by *separator*.\nThe separator is a built-in command and may be coded in different bytes\n(depending on command count, see “Commands and Parameters” section below).\nBut in any languages `0x00` byte is a separator.\n\n    \u003crules\u003e     ::= ( \u003crule\u003e \u003cseparator\u003e )*\n    \u003cseparator\u003e ::= 0x00 | \u003cseparator bytes in this language\u003e\n\n### Commands and Parameters\n\nA rule contains pairs of *commands* and an optional *parameter*. Command byte\nbegins with `0` bit and command number is encoded by next 7 bits. Any other\nbytes (beginning with `1`) after command encode parameter number. For example,\n2 bytes `1aaaaaaa` and `1bbbbbbb` encode parameter with `aaaaaaabbbbbbb` value.\n\n    \u003crule\u003e      ::= ( \u003ccommand\u003e ( \u003cparameter\u003e )? )*\n    \u003ccommand\u003e   ::=   0xxxxxxx\n    \u003cparameter\u003e ::= ( 1xxxxxxx )*\n\nThere are 127 different commands number in one command byte, but language may\nhave less commands. A mutation can generate any bytes and Evolu Lang must try to\ndecode any of them. So, commands are marked numbers in a circle: if language\nhave 3 commands (`separator`, `a`, `b`), 0 will be encode `separator`, 1 – `a`,\n2 – `b`, but 3 will encode `separator` again, 4 – `a`, etc.\n\nIn language description commands may specify format of it’s parameter.\nParameters can be unsigned integers (simple encoded by bits in parameter bytes)\nor list of values (encode in cycle, like commands).\n\n### Conditions\n\nThere is special command type – *condition*. If all conditions in a rule are\ntrue, the rule’s commands will execute.\n\nIf a rule doesn’t have any conditions it will run once at start as constructor.\n\n### Standard Commands Pack\n\nYou can create your own language with Evolu Lang, but for common tasks it has\nthe standard commands pack to create Turing completeness languages.\n\nConditions:\n\n* `if_signal` will be true, when program receives input signal (its name will\n  be taken from parameter). If the rule contains several these conditions with\n  different signals, all `if_signal` conditions will be true by any of these\n  signals (because, program may receive only one signal at a moment).\n* `if_var_more_0` will be true if variable (its name will be taken from\n  condition parameter) will be more, than zero.\n\nCommands:\n\n* `send_signal` will send output signal (its name will be taken from parameter).\n* `var_up` will increase variable from parameter.\n* `var_down` will decrease variable from parameter.\n\nThe developer must define, what input and output signals will be in the\nlanguage, but variables can be added dynamically by mutation.\n\n## How To\n\nFor example, we will generate program (by genetic programming), which calculates\n`tick` signals and on `result` signal it sends whether an `even` or an `odd`\ntick count it received.\n\n### Language\n\nLike XML, Evolu Lang is just a syntax format. So you need to define a language\nfor your task using the `evolu.lang.add(name, initializer)` function.\nIt receives a language name (to use it as a prefix in the source code for\nstoring and transferring the program) and function (which adds the language\ncommands to `this`), and returns a new language.\n\nFor the common cases you can use the standard commands pack, and you only need\nto define the input/output signals.\n\n    var lang = evolu.lang.add('EVEN-ODD', function() {\n        this.add(evolu.lang.standard.input('tick', 'result'))\n        this.add(evolu.lang.standard.output('even', 'odd'))\n        lang.add(evolu.lang.standard.variables)\n    })\n\n### Population\n\nGet any genetic algorithm library or write it by yourself. Use a byte array\n(array of integers from `0` to `255`, for example `[0, 255, 13, 68, 145]`) as\ngenes.\n\n    var population = []\n    // Add 100 genes to the first population\n    for (var i = 0; i \u003c 100; i++) {\n        var gene = []\n        // Each gene will have random length\n        while (Math.random \u003c 0.9) {\n            // Add a random byte to the current gene\n            gene.push(Math.round(255 * Math.random()))\n        }\n    }\n\n### Mutation\n\n*Note that the integers in an array must be from `0` to `255`.*\n\nIn the genetic algorithm you can use any types of mutation for a byte stream\n(a lot of libraries contain them). You can add, change, delete and\nmove bytes in the array.\n\nYou can use crossover to mix arrays or just move a part of bytes from one array\nto another (like horizontal gene transfer).\n\n### Selection\n\nTo calculate fitness for each gene in the population, you need to compile\neach byte array:\n\n    var program = lang.compile(population[i])\n\nSend the data to the program and check its output data to calculate fitness.\nIt’s like automatic unit testing, but your test must return a score,\nnot just a pass/fail result.\n\nIf you use the standard commands pack, you can use the `receive_signal` event\nto listen output signals and the `signal` function to send input signals:\n\n    output = []\n    program.listen('receive_signal', function(signal) {\n        output.push(signal)\n    })\n    \n    program.signal('tick').signal('tick').signal('result')\n    // Some hypothetical API\n    check(output).to_contain('even')\n    \n    output = []\n    program.signal('tick').signal('result')\n    check(output).to_contain('odd')\n\n### Saving\n\nWhen you generate a program for your demands, you can save it to a disk or send\nto a server:\n\n    var source = bestProgram.toSource()\n\nSource is a string with `EVOLU:` and a language name in prefix. For example,\n`\"EVOLU:EVEN-ODD:\\x04\\x80\\x00\\x01\\x80\\x03\\x80\\x05…\"`.\n\nUse `evolu.lang.compile(string)` to automatically find a language (using the source\nprefix) and compile the bytes into a program:\n\n    bestProgram == evolu.lang.compile(bestProgram.toSource())\n\n## Testing\n\n1. Install Rake (Ruby make) and RubyGems (Ruby package manager).\n   For example, on Ubuntu:\n   \n       sudo apt-get install rake rubygems\n\n2. Install `jasmin` gem:\n\n       gem install jasmin\n\n3. Run test server:\n\n       rake jamsin\n\n4. Open \u003chttp://localhost:8888\u003e.\n\n## License\n\nEvolu Lang is licensed under the GNU Lesser General Public License version 3.\nSee the LICENSE file or http://www.gnu.org/licenses/lgpl.html.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fevolu-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fai%2Fevolu-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fevolu-lang/lists"}