diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 072f919ad..1d6ab3aaa 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,4 +1,4 @@ -name: build docs +name: docs on: push: branches: @@ -12,10 +12,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: "3.x" + python-version: "3.8" - uses: actions/cache@v4 with: key: ${{ github.ref }} path: .cache - - run: pip install mkdocs-material mkdocs-minify-plugin mkdocstrings[python] + - run: pip install mkdocs-material=9.7.0 mkdocs-minify-plugin=0.8.0 mkdocstrings[python]==0.30.1 - run: mkdocs gh-deploy --force diff --git a/docs/metta.md b/docs/metta.md new file mode 100644 index 000000000..c2c9fdbc3 --- /dev/null +++ b/docs/metta.md @@ -0,0 +1,601 @@ +# Syntax + +## S-expression grammar + +This is the S-expression grammar of the MeTTa language. The program is +consisted of the atoms prefixed or not prefixed by the `!` sign. + +``` +METTA ::= { [ '!', [ DELIM ] ], ATOM, [ DELIM ] } ; + +ATOM ::= SYMBOL | VARIABLE | GROUNDED | EXPRESSION ; +SYMBOL ::= WORD; +WORD ::= ( CHAR | '#' ), { CHAR | '"' | '#' } ; +VARIABLE ::= '$', ( CHAR | '"' ), { CHAR | '"' } ; +GROUNDED ::= STRING | WORD ; +EXPRESSION ::= '(', { ATOM, [ DELIM ] }, ')' ; + +STRING ::= '"', { CHAR | WHITESPACE | '#' | '(' | ')' | ';' }, '"' ; +COMMENT ::= ';', { CHAR | ' ' | '\t' | '"' | '#' | '(' | ')' | ';' } ! EOL ; +DELIM ::= { WHITESPACE | COMMENT } ; + +CHAR ::= ; +WHITESPACE ::= ' ' | '\t' | EOL ; +EOL ::= '\r' | '\n' ; +``` + +(*) Symbol atom can start with the `!` character. For example `!name` is a +valid symbol and not an atom prefixed by `!`. This is an artifact of the HE +parser evolution process and not a strong requirement. + +(*) The `#` character is used internally by HE to represent the automatically +generated variables. It is the reason why `#` is reserved and cannot be used +inside a variable name. + +(*) Whitespace character is any character for which `char.is_whitespace()` +method from the Rust standard library returns true. + +The symbol and grounded atoms are very similar from the grammar perspective. +The difference is in the way how they are represented in memory. A symbol can +be considered an id. A grounded atom on the other hand may have state and +usually has some natural representation in the host language (i.e. Rust, Python +or other programming language). + +The grounded atoms are constructed from the `WORD` or `STRING` grammar tokens +by a tokenizer. Tokenizer is a collection of the pairs `(, +)`. If the `WORD` or `STRING` token is matched by one of +the `` from the tokenizer then a grounded atom is constructed by +``. `` gets the matched token as an +argument. For instance it is possible instantiating the integer grounded atoms +by adding the pair `([0-9]+, )` into the tokenizer. + +## Special expressions + +This section lists atoms with some special meaning in the interpreter. The +expressions listed below are not the only expressions possible when the special +atoms are used. For example having the `(= ...)` expression with more than two +arguments is absolutely normal. In such case the interpreter will not recognize +it as a function definition but the expression still can be the part of the +knowledge base. + +In general the symbols listed below are similar to the reserved words in the +other languages. In MeTTa the programmer still can use these symbols in an +unusual context but it should be noted that the interpreter has a special +meaning for them. + +### Function expression + +The `=` atom is used to define a function expression in the following form: +``` +(= ) +``` + +For example the `if` function can be defined as following: +``` +(= (if True $then $else) $then) +(= (if False $then $else) $else) +``` + +### Type assignment + +The `:` atom is used to define the type of the atom: +``` +(: ) +``` + +For example the `if` function could have the following type definition: +``` +(: if (-> Bool Atom Atom $t)) +``` + +### Function type + +The `->` atom is used to introduce a type of a function: +``` +(-> arg1_type arg2_type ... argN_type ret_type) +``` + +For example the type of the `if` function: +``` +(-> Bool Atom Atom $t) +``` + +### Elementary types + +There are the number of symbols which are used as the basic types: +- `Type` - the type of any type +- `%Undefined%` - the unknown type +- `Atom` - the type of any atom +- `Symbol` - the type of the symbol atom +- `Variable` - the type of the variable atom +- `Expression` - the type of the expression atom +- `Grounded` - the type of the grounded atom + +All of them except the `Type` affect the order of the expression evaluation. +Last four types correspond to the types of the atoms defined by the grammar. +These types plus `Atom` are referred below as meta-types. `Atom` is a special +meta-type which matches any atom and used for changing the order of evaluation. + + +### Special function results + +- `Empty` - the function doesn't return any result, it is different from the + void or unit result in other languages +- `NotReducible` - returns the unchanged function call instead +- `Error` - the error result constructor + +The `Error` expression has the following format: +``` +(Error ) +``` +where `` is either a string or a symbol or one of the following: +- `StackOverflow` - returned by the interpreter when the stack depth is + restricted and maximum depth is reached +- `NoReturn` - this error is reserved by the minimal MeTTa interpreter and + should not be returned if program doesn't have `(function ...)` minimal MeTTa + blocks (see [minimal MeTTa documentation](./minimal-metta.md#functionreturn) + for more information) +- `IncorrectNumberOfArguments` - the number of argument in the call doesn't + equal to the number of parameters of the called function +- `(BadArgType )` - the argument + type error +- `(BadType )` - the type cast error + +(*) `ErrorType` is a type of the error atom which is returned by the `Error` +type constructor. This symbol has no special meaning in HE. On the other hand +it could be used to introduce custom type constructors. This could be +implemented by making an interpreter treating any expression which has +`ErrorType` type as an error. + +### Minimal MeTTa instructions + +The minimal MeTTa is an attempt to create an assembly language for MeTTa. +Minimal MeTTa related atoms are listed here because while they are not a part +of the standard library they are still recognized and evaluated by the MeTTa +interpreter. Full documentation on minimal MeTTa can be found at +[minimal-metta.md](./minimal-metta.md). + +(*) It is possible to implement MeTTa interpreter in minimal MeTTa and HE +interpreter is implemented in this way. Implementing minimal MeTTa interpreter +in pure MeTTa is not possible. But on the other hand one could implement +minimal MeTTa as a MeTTa library containing the corresponding grounded +functions. Some internal APIs of HE should be changed to make this doable. Main +reason is that the grounded functions don't have access to the context of the +MeTTa interpreter, for instance to the current working atomspace. + +Minimal MeTTa instructions: +- `(eval )` - makes one step of the evaluation +- `(evalc )` - makes one step of the + evaluation in the context of the passed space +- `(chain