Skip to content

Instantly share code, notes, and snippets.

@okram
Last active December 13, 2019 00:22
Show Gist options
  • Save okram/0af2ead5fcf07efe1ddf86cdbff91764 to your computer and use it in GitHub Desktop.
Save okram/0af2ead5fcf07efe1ddf86cdbff91764 to your computer and use it in GitHub Desktop.
/**
BRANCHING IN mm-ADT
The Rogdopalous -- Winter 2019 [mm-adt.org]
The [branch] instruction takes an incoming obj and sends a clone of it
down each internal split/branch/fork.
There 4 different ways to express the same computation.
**/
A diagam of the example branching structure used throughout the writeup. 3 branches:
1. 2 => int : How is 2 represented/encoded/embedded in the set of all integers, int. (type token)
2. 2 => 2 : How is 2 denoted in 2? (instance token)
3. 2 => [is > 1] : How is 2 denoted by the set of all things greater than 1? x => [is,bool] => x{?} (instruction token -- filter instruction more specifically)
// 4. 2 => 2->2 : How is 2 encoded as a record of key/value pairs? (cases/pattern matching)
/--int--------\
--2-------|---2--------------->
\-[is > 1]----/
// as a 'product', branch takes a list of objs which can be 'types','instances',or instructions. lst => [zero] => [;]
mmlang> 2 => [branch,[int;2;[is > 1]]]
==>2
==>2
==>2
// as a 'ring', addition and subtraction denote splitting and merging of the processing pipeline. +,[plus].
mmlang> 2 => [int + 2 + [is > 1]]
==>2
==>2
==>2
// as an 'instruction' w/ arguments, each arg after the 'branch' opcode is a branch. inst
mmlang> 2 => [branch,int,2,[is > 1]]
==>2
==>2
==>2
// as a 'case statement', keys are predicates and values are branches. 1->2->3 => [[1:2]:3] // -> and : are key/value constructors
mmlang> 2 => [int->int + 2->2 + [is,[gt,1]]->[is > 1]]
==>2
==>2
==>2
// all the expressions above have the same primary bytecode encoding. (stage 1 compilation -- mmlang => mmadt)
// universal branching with records (rec).
mmlang> [branch,[int;2;[is > 1]]]
==>[branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
mmlang> [int + 2 + [is > 1]]
==>[branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
mmlang> [branch,int,2,[is > 1]]
==>[branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
mmlang> [int->int + 2->2 + [is,[gt,1]]->[is > 1]]
==>[branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
// type checking, inference, and rewriting occurs via abstract interpretation. (stage 2-N compilations -- mmadt => lst => ring => inst => rec
// compute with the int token and you are calculating
// what can be logically said about the behavior
// of all ints through this instruction sequence.
mmlang> int => [branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
==>int
==>2{?}
==>int{?} <= (int)=>[is,bool <= [gt,1]]
/*
^
|--- 3 results are produced (three branches).
|------ we will definately get an int.
|------ we may or may not get back a 2. {0,1} == {?} (quantifiers)
|------ we may or may may not get back an int.
|
| this complex is called as a "reference" (related to futures/streams/partial_computation/closure/curry)
| the general syntax is obj <= inst --- how is the object (obj) instantiated (dereferenced) via the instruction sequence (inst)?
When an 'instance' token is inserted into the stream (left-to-right flows),
the results are:
*/
mmlang> 2 => [branch,[int:int,2:2,[is,[gt,1]]:[is,[gt,1]]]]
==>2
==>2
==>2
/**
The same algorithm type checks, compiles, and executes the instructions.
The behavior of the system is encoded in the complexity of the obj
being passed through. If the 'sets' are smaller (e.g. the singleton 2),
then your results are more precise. If your 'sets' are larger (e.g. the
set of all integers), then your results describe general properties
of the set as a whole.
**/
@okram
Copy link
Author

okram commented Dec 12, 2019

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// compiling, type checking, inference, and rewriting are terms denoting the same model operations.  //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    mmlang => mmadt => lst => ring => inst


              How is mmlang syntax embedded in mmadt structures?                    (union of the below)
              How is mmadt embedded in lst?                                          (the [str;obj])
              How is the mmadt lst embedded in ring?                               (the * + stream ring theory)
              How is the mmadt ring embedded in inst?                             (the instructions opcode/args)

All we do is map tokens onto tokens via the binary "map to"-operator  =>:

            =>: obj X obj -> obj.          // math notation for function signatures
 
   Its like set intersections.
   Its like chained filters.
   Its like an algebraic monoid.
   Its like a sequence of instructions.

These are various models of the same abstract concept. There exists morphisms (injective/surjective-style) between them.

+ - / 0 1 *     -- for talking to your model algebraically.
inst branch  -- for talking to your model mechanically.
[str;obj]        -- for talking to your model in lisp-like-stylie.

The maps-from and maps-to operators of the form <= and =>  mutate the 
state-monad/traverser/obj-thread's internal structure such
that the operators have different signatures and axioms.
This is how models (isolated algebraic environments) are embedded (encoded) in one another. 

This is mm-ADT. 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment