Repository: asteroid-lang/asteroid (language: python)

Issue:
The %pattern type has to include structures
Our new `%pattern` type has to include everything that can be considered a pattern.  E.g.
```
assert( (1,2) is %pattern ).
```
should work.  That basically means everything structural should be included in this type.  However, functions, function symbols, and operator symbols need to be excluded since these represent computations and not structures.
The %pattern type has to include structures
Our new `%pattern` type has to include everything that can be considered a pattern.  E.g.
```
assert( (1,2) is %pattern ).
```
should work.  That basically means everything structural should be included in this type.  However, functions, function symbols, and operator symbols need to be excluded since these represent computations and not structures.


Discussion / hints:

Fix patch:
diff --git a/asteroid/frontend.py b/asteroid/frontend.py
index 68716e79..d0097c2c 100644
--- a/asteroid/frontend.py
+++ b/asteroid/frontend.py
@@ -44,11 +44,10 @@ def dbg_print(string):
     } | ops
 
 exp_lookahead = {
-    'QUOTE',
     'PATTERN',
     'LCONSTRAINT',} | primary_lookahead
 
-exp_lookahead_no_ops = exp_lookahead - ops - {'QUOTE'}
+exp_lookahead_no_ops = exp_lookahead - ops
 
 primary_lookahead_no_ops = exp_lookahead_no_ops
 
@@ -524,41 +523,27 @@ def body_defs(self):
 
         return ('body-list', ('list', body_list))
 
-    ###########################################################################################
-    # pattern
-    #    : exp
-    def pattern(self):
-        dbg_print("parsing PATTERN")
-        e = self.exp()
-        return e
-
     ###########################################################################################
     # exp
-    #    : quote_exp
+    #    : pattern
     def exp(self):
         dbg_print("parsing EXP")
-        v = self.quote_exp()
+        v = self.pattern()
         return v
 
     ###########################################################################################
-    # quote_exp
-    #    : QUOTE exp
-    #    | PATTERN WITH? exp
+    # pattern
+    #    : PATTERN WITH? exp
     #    | '%[' exp ']%'
     #    | head_tail
-    def quote_exp(self):
-        dbg_print("parsing QUOTE_EXP")
+    def pattern(self):
+        dbg_print("parsing PATTERN")
 
-        if self.lexer.peek().type == 'QUOTE':
-            self.lexer.match('QUOTE')
-            v = self.exp()
-            return ('quote', v)
-        # 'pattern with' is just the long version of the quote char
-        elif self.lexer.peek().type == 'PATTERN':
+        if self.lexer.peek().type == 'PATTERN':
             self.lexer.match('PATTERN')
             self.lexer.match_optional('WITH')
             v = self.exp()
-            return ('quote', v)
+            return ('pattern', v)
         elif self.lexer.peek().type == 'LCONSTRAINT': #constraint-only pattern match
             self.lexer.match('LCONSTRAINT')
             v = self.exp()
diff --git a/asteroid/globals.py b/asteroid/globals.py
index 25cfdf05..18bb7b5e 100644
--- a/asteroid/globals.py
+++ b/asteroid/globals.py
@@ -151,3 +151,19 @@ def __str__(self):
 }
 
 ###########################################################################################
+# list of structures that constitute patterns
+
+patterns = [
+    'pattern',
+    'id',
+    'string',
+    'real',
+    'integer',
+    'list',
+    'tuple',
+    'boolean',
+    'none',
+    'object',
+    'struct',
+    'typematch',
+]
diff --git a/asteroid/grammar.txt b/asteroid/grammar.txt
index 6308fde6..17d7301e 100644
--- a/asteroid/grammar.txt
+++ b/asteroid/grammar.txt
@@ -33,7 +33,6 @@
     | WHILE exp DO stmt_list END
     | REPEAT DO? stmt_list UNTIL exp '.'?
     | IF exp DO stmt_list (ELIF exp DO stmt_list)* (ELSE DO? stmt_list)? END
-    | MATCH exp WITH? (CASE pattern DO stmt_list)+ (OTHERWISE DO? stmt_list)? END
     | TRY DO? stmt_list (CATCH pattern DO stmt_list)+ END
     | THROW exp '.'?
     | BREAK '.'?
@@ -69,15 +68,11 @@
    to highlight the SEMANTIC difference between patterns and
    expressions.
   */
-  pattern
-    : exp
-
   exp
-    : quote_exp
+    : pattern
 
-  quote_exp
-    : QUOTE exp
-    | PATTERN WITH? exp
+  pattern
+    : PATTERN WITH? exp
     | '%[' exp ']%'      /* constraint-only pattern match */
     | head_tail
 
diff --git a/asteroid/lex.py b/asteroid/lex.py
index a81a8f85..31cc5fb1 100644
--- a/asteroid/lex.py
+++ b/asteroid/lex.py
@@ -89,7 +89,6 @@
     (r'\.',                                                     'DOT'),
     (r',',                                                      'COMMA'),
     (r'=',                                                      'ASSIGN'),
-    (r'\'',                                                     'QUOTE'),
     # this is the catch-all pattern, it has to be
     # here do that we can report illegal characters
     # in the input.
@@ -101,7 +100,6 @@
 implicit_token_types = [
     'INTEGER',
     'REAL',
-    'CMATCH',
 ]
 
 class Token:
diff --git a/asteroid/state.py b/asteroid/state.py
index 251a8517..7a2d6cbf 100644
--- a/asteroid/state.py
+++ b/asteroid/state.py
@@ -1,7 +1,7 @@
 ###########################################################################################
 # Asteroid State Object
 #
-# (c) Lutz Hamel, University of Rhode Island
+# (c) University of Rhode Island
 ###########################################################################################
 
 from asteroid.symtab import SymTab
@@ -14,7 +14,7 @@ def initialize(self):
         self.symbol_table = SymTab()
         self.modules = [] # loaded modules
         self.AST = None
-        self.ignore_quote = False # used to evaluate quoted expressions
+        self.ignore_pattern = 0 # used to evaluate pattern expressions
         self.constraint_lvl = 0 # used to evaluate constraint-only patterns
         self.cond_warning = False # used to indicate if conditional subsumption
                                   # warning has been displayed
diff --git a/asteroid/support.py b/asteroid/support.py
index 897b6131..15788947 100644
--- a/asteroid/support.py
+++ b/asteroid/support.py
@@ -257,8 +257,8 @@ def term2string(term):
         term_string += term2string(args)
         return term_string
 
-    elif TYPE == 'quote':
-        # we are printing out a term - just ignore the quote operator
+    elif TYPE == 'pattern':
+        # we are printing out a term - just ignore the pattern operator
         val = term[1]
         return term2string(val)
 
@@ -316,180 +316,18 @@ def term2string(term):
         term_string += term2string(state.symbol_table.lookup_sym(pName))
         return term_string
 
-    elif TYPE == 'cmatch':              # Handle a conditional pattern
-
-        (CMATCH,CVALUE,CEXPRESSION) = term
-
-        #Check for a compound condtional( ANDs and ORs )
-        if (((CEXPRESSION[1])[1] == '__and__') or ((CEXPRESSION[1])[1] == '__or__')):
-            return compound_relational_to_string(term)
-
-        try:
-            (NAMED_PATTERN,ID,pattern) = CVALUE
-        except:
-            ID = CVALUE
-            pattern = CVALUE
-        (APPLY,expression_type,expressions) = CEXPRESSION
-
-        if ((expressions[0] == 'tuple')):
-
-            if ((expression_type[1])[0] == '_'): #Handle conditional prebuit operation
-                (TUPLE,[ expression_lhs , expression_rhs ]) = expressions
-
-                term_string = term2string(ID) + ':'
-                term_string += term2string(pattern)
-                term_string += " %" + "if "
-                term_string += term2string(expression_lhs)
-
-                if expression_type[1] == '__gt__':
-                    term_string += ' > '
-                elif expression_type[1] == '__lt__':
-                    term_string += ' < '
-                elif expression_type[1] == '__le__':
-                    term_string += ' <= '
-                elif expression_type[1] == '__ge__':
-                    term_string += ' >= '
-                elif expression_type[1] == '__eq__':
-                    term_string += ' == '
-                elif expression_type[1] == '__ne__':
-                    term_string += ' =/= '
-
-                term_string += term2string(expression_rhs)
-
-            else:               #Handle a function with multiple args
-                (TUPLE,EXPRESION_LIST) = expressions
-
-                term_string = term2string(ID)+ ':'
-                term_string += term2string(pattern)
-                term_string += " if "
-                term_string += expression_type[1] + '( '
-
-                for expression in EXPRESION_LIST:
-                    term_string += term2string(expression)
-                    term_string += ', '
-                term_string = term_string[:-2]
-                term_string += ' )'
-
-        elif (expressions[0] == 'none'): #Handle a function with no arguments
-            term_string = term2string(ID)+ ':'
-            term_string += term2string(pattern)
-            term_string += " if "
-            term_string += expression_type[1] + '()'
-
-        elif (expressions[0] in ['id','integer','real','sting','boolean']): #Handle a function with one arguments
-            term_string = term2string(ID)+ ':'
-            term_string += term2string(pattern)
-            term_string += " if "
-            term_string += expression_type[1] + '( '
-            term_string += str(expressions[1]) + ' )'
-
-        return term_string
+    elif TYPE == 'if-exp':              # Handle a conditional pattern
+        (IF_EXP,EXPRESSION,value,NULL) = term
+        # conditions can be arbitrary computations not structural terms
+        # therefore we don't print the whole tree.
+        return term2string(value)+' if (condition...)'
 
     else:
         #lhh print(term)
         raise ValueError(
             "unknown type '{}' in term2string"
             .format(TYPE))
-##############################################################################################
-# term2string helper
-# This function takes in a relational conditional expression from a conditional pattern clause
-# and then returns that expression as a nicely formatted string
-#
-# Ths realtional expression is expected to come in its raw nested tuple/AST form from the Asteroid
-# Interpreter.
-def walk_relational_expr(term):
-
-    # Unpack
-    (APPLY,expression_type,args) = term
-    (TUPLE,arg_list) = args
-
-    term_string = ''
-    term_string += term2string(arg_list[0])
-
-    # Parse and write the argument type
-    if expression_type[1] == '__gt__':
-        term_string += ' > '
-    elif expression_type[1] == '__lt__':
-        term_string += ' < '
-    elif expression_type[1] == '__le__':
-        term_string += ' <= '
-    elif expression_type[1] == '__ge__':
-        term_string += ' >= '
-    elif expression_type[1] == '__eq__':
-        term_string += ' == '
-    elif expression_type[1] == '__ne__':
-        term_string += ' =/= '
-    else:
-        return ''
-
-    term_string += term2string(arg_list[1])
-
-    return term_string
-
-##############################################################################################
-# term2string helper
-#
-# This function helps construct a string from a compound relational conditional pattern clause.
-# The and/or nodes are walked down as the string is constructed.
-# This function takes in the raw term/AST from the compound relational conditional pattern clause
-# in the nested tuple/AST form.
-#
-# Example clause:
-#               with (x) if x <= 10 and x > 1 or x > 2 and x < 9 or x < 7 do
-# Example output:
-#               x: if x <= 10 and x > 1 or x > 2 and x < 9 or x < 7
-def compound_relational_to_string(term):
-
-    #Check if we have passed by the relation type before
-    not_first_pass_and = False
-    not_first_pass_or = False
-
-    # If its the first time we have seen this we need to write the header/pattern name
-    # before recursing
-    if (term[0] == 'cmatch'):
-        (CMATCH,pattern,apply_list) = term
-        term_string = term2string(pattern)
-        term_string += ': if '
-        term_string += compound_relational_to_string(apply_list)
-        return term_string
-
-    # Else we just unpack the node and peek at the upcoming operation
-    else:
-        (APPLY,operation,apply_list) = term
-        term_string = ''
-        op_name = operation[1]
-
-    # Walk down the tree, constucting the string along the way
-    if ( op_name == '__or__' ):
-
-        for expr in apply_list[1]:
-
-            # Add seperator if appropriate
-            if not_first_pass_or:
-                term_string += " or "
-            else:
-                not_first_pass_or = True
-
-            #write the current term to string
-            term_string += compound_relational_to_string(expr)
-    elif ( op_name == '__and__'):
-
-        for expr in apply_list[1]:
-
-            # Add seperator if appropriate
-            if not_first_pass_and:
-                term_string += " and "
-            else:
-                not_first_pass_and = True
-
-            #write the current term to string
-            if (expr[1])[1] in ['__and__','__or__']:
-                term_string += compound_relational_to_string(expr)
-            term_string += walk_relational_expr(expr)
-    else:
-        term_string += walk_relational_expr(term)
 
-    return term_string
 ##############################################################################################
 # Function head_tail_length determines the lenth of a head-tail node by walking to the end.
 # The length is then returned from this function as in integer.
diff --git a/asteroid/walk.py b/asteroid/walk.py
index 1d082508..880ca0b8 100644
--- a/asteroid/walk.py
+++ b/asteroid/walk.py
@@ -110,9 +110,8 @@ def unify(term, pattern, unifying = True ):
     elif ((not unifying) and (term[0] == 'deref')):
 
         # Unpack a term-side first-class pattern if evaluating redundant clauses
-        (ID, sym) = term[1]
-        term = state.symbol_table.lookup_sym(sym)
-        return unify(term[1], pattern, unifying)
+        term_pattern = walk(term[1])
+        return unify(term_pattern, pattern, unifying)
 
     ### Asteroid value level matching
     elif pattern[0] == 'object' and term[0] == 'object':
@@ -185,7 +184,11 @@ def unify(term, pattern, unifying = True ):
         if else_exp[0] != 'null':
             raise ValueError("conditional patterns do not support else clauses")
 
-        return unify(pexp,pattern,False)
+        #return unify(pexp,pattern,False)
+        # Otherwise if the term is not another cmatch the clauses are correctly ordered.
+        raise PatternMatchFailed(
+            "Conditional patterns not supported.")
+
 
     elif pattern[0] == 'typematch':
         typematch = pattern[1]
@@ -221,7 +224,9 @@ def unify(term, pattern, unifying = True ):
                     .format(typematch, term[0]))
 
         elif typematch == 'pattern':
-            if term[0] == 'quote':
+            # any kind of structure can be a pattern, and variables
+            # see globals.py for a definition of 'patterns'
+            if term[0] in patterns:
                 return []
             else:
                 raise PatternMatchFailed(
@@ -285,16 +290,16 @@ def unify(term, pattern, unifying = True ):
             "pattern of type '{}' not allowed in pattern matching"
             .format(pattern[0]))
 
-    elif pattern[0] == 'quote':
-        # quotes on the pattern side can always be ignored
+    elif pattern[0] == 'pattern':
+        # pattern operator on the pattern side can always be ignored
         # --TODO double check - ttc
-        if term[0] == 'quote':
+        if term[0] == 'pattern':
             return unify(term[1], pattern[1], unifying)
         else:
             return unify(term, pattern[1], unifying)
 
-    elif term[0] == 'quote' and pattern[0] not in ['id', 'index']:
-        # ignore quote on the term if we are not trying to unify term with
+    elif term[0] == 'pattern' and pattern[0] not in ['id', 'index']:
+        # ignore pattern operator on the term if we are not trying to unify term with
         # a variable or other kind of lval
         return unify(term[1], pattern, unifying)
 
@@ -322,10 +327,12 @@ def unify(term, pattern, unifying = True ):
         unifier = (pattern, term)
         return [unifier]
 
-    elif term[0] == 'id' and unifying: # variable in term not allowed
-        raise PatternMatchFailed(      # when unifying
-            "variable '{}' in term not allowed"
-            .format(term[1]))
+# lhh: looking at patterns as values we are now allowed to match
+# against patterns as terms where the terms now include variables.
+#    elif term[0] == 'id' and unifying: # variable in term not allowed
+#        raise PatternMatchFailed(      # when unifying
+#            "variable '{}' in term not allowed"
+#            .format(term[1]))
 
     elif pattern[0] == 'id': # variable in pattern add to unifier
         sym = pattern[1]
@@ -561,6 +568,10 @@ def read_at_ix(structure_val, ix):
         else:
             ix_val = walk(ix)
 
+    elif structure_val[0] == 'pattern':
+        # simple patterns are just structures - skip the pattern operator
+        return read_at_ix(structure_val[1], ix)
+
     else:
         raise ValueError("'{}' is not indexable".format(structure_val[0]))
 
@@ -627,6 +638,10 @@ def store_at_ix(structure_val, ix, value):
         else:
             ix_val = walk(ix)
 
+    elif structure_val[0] == 'pattern':
+        # simple patterns are just structures - skip the pattern operator
+        return store_at_ix(structure_val[1], ix, value)
+
     else:
         raise ValueError("'{}' is not a mutable structure".format(structure_val[0]))
 
@@ -1225,11 +1240,11 @@ def eval_exp(node):
     #lhh
     #print("after expand: {}".format(exp_val_expand))
     # now walk the actual term
-    state.ignore_quote = True
+    state.ignore_pattern += 1
     exp_val = walk(exp_val_expand)
     #lhh
     #print("after walk: {}".format(exp_val))
-    state.ignore_quote = False
+    state.ignore_pattern -= 1
     return exp_val
 
 #########################################################################
@@ -1603,12 +1618,10 @@ def walk(node):
     'boolean'       : lambda node : node,
     'object'        : lambda node : node,
     'eval'          : eval_exp,
-    # quoted code should be treated like a constant if not ignore_quote
-    'quote'         : lambda node : walk(node[1]) if state.ignore_quote else node,
+    # pattern code should be treated like a constant if not ignore_pattern
+    'pattern'         : lambda node : walk(node[1]) if state.ignore_pattern else node,
     # constraint patterns
     'constraint'    : constraint_exp,
-    # the following is now handled with an if-exp
-    #'cmatch'        : constraint_exp,
     'typematch'     : constraint_exp,
     # type tag used in conjunction with escaped code in order to store
     # foreign objects in Asteroid data structures
diff --git a/docs/Asteroid in Action.rst b/docs/Asteroid in Action.rst
index 956492fe..7c2167d5 100644
--- a/docs/Asteroid in Action.rst
+++ b/docs/Asteroid in Action.rst
@@ -10,11 +10,10 @@
 
 
 
-
-
 ..
    *** DO NOT EDIT; MACHINE GENERATED ***
 
+
 .. highlight:: none
 
 Asteroid in Action
@@ -32,10 +31,12 @@ Challenge: Hello, World!
 
 The canonical ``Hello, World!`` program.  The easiest way to write this in Asteroid is,
 ::
+
   load system io.
 
   io @println "Hello, World!".
 
+
 Output::
 
     Hello, World!
@@ -49,6 +50,7 @@ Challenge: Greet a person
 
 Here is our first solution using a separate function for each of the steps,
 ::
+
   load system io.
 
   io @print ("Enter your name: ").
@@ -56,19 +58,24 @@ Here is our first solution using a separate function for each of the steps,
   io @print ("Hello, "+name+"!").
 
 
+
 Letting the function ``input`` do the prompting,
 ::
+
   load system io.
 
   let name = io @input("Enter your name: ").
   io @println ("Hello, "+name+"!").
 
+
 Doing everything in one step,
 ::
+
   load system io.
 
   io @println ("Hello, "+io @input("Enter your name: ")+"!").
 
+
 Challenge: String length
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -76,11 +83,13 @@ Challenge: String length
 
 In order to print the length of a string we can use the function ``len`` available in the ``util`` module,
 ::
+
   load system io.
 
   load "util".
   io @println (len("Hello!")).
 
+
 Output::
 
     6
@@ -88,10 +97,12 @@ Output::
 
 We can also use the string member function ``length`` in order to compute the length of the string,
 ::
+
   load system io.
 
   io @println ("Hello!" @length()).
 
+
 Output::
 
     6
@@ -105,6 +116,7 @@ Challenge: Unique digits
 In order to accomplish this we take advantage of the string ``explode`` function and the ``sort`` function on lists.
 Finally we use the ``reduce`` function to map a list with repeated digits to a list with unique digits,
 ::
+
   load system io.
 
   function unique with (x,y) do
@@ -121,6 +133,7 @@ Finally we use the ``reduce`` function to map a list with repeated digits to a l
   io @println digits.
   assert(digits == ["1","2","3"]).
 
+
 Output::
 
     [1,2,3]
@@ -138,6 +151,7 @@ Challenge: Reverse a string
 
 We use the ``explode`` function to turn a string into a list of characters. Then, we reverse the list and turn it back into a string using the ``join`` function,
 ::
+
   load system io.
 
   let str = "Hello, World!" @explode()
@@ -146,6 +160,7 @@ We use the ``explode`` function to turn a string into a list of characters. Then
   io @println str.
   assert(str == "!dlroW ,olleH").
 
+
 Output::
 
     !dlroW ,olleH
@@ -157,12 +172,14 @@ Challenge: Removing blanks from a string
 > Remove leading, trailing, and double spaces from a given string.
 
 ::
+
   load system io.
   let str = "   Hello  ,   World    !   " @trim()
                                           @replace("  ","").
   io @println str.
   assert(str == "Hello, World!").
 
+
 Output::
 
     Hello, World!
@@ -177,6 +194,7 @@ In this task, we will form the ``CamelCase`` variable for names from a given phr
 Names created in this style are built of several words, each of which starts
 with a capital letter.
 ::
+
   load system io.
 
   function title with w do
@@ -199,6 +217,7 @@ with a capital letter.
   io @println camel_str.
   assert(camel_str == "OnceUponATime").
 
+
 Output::
 
     OnceUponATime
@@ -209,6 +228,7 @@ Challenge: Incrementing filenames
 
 > Generate a list of filenames like file1.txt, file2.txt, etc.
 ::
+
   load system io.
 
   let root = "file".
@@ -218,6 +238,7 @@ Challenge: Incrementing filenames
       io @println (root+i+ext).
   end
 
+
 Output::
 
     file1.txt
@@ -234,6 +255,7 @@ Challenge: Random passwords
 
 In our solution we take advantage of Asteroid's ``Pick`` object.  The ``Pick`` object maintains a list of items that we can randomly select from using the ``pick`` member function.  As input to the ``Pick`` object, we compute a bunch of lists of characters that are useful for password construction.  The function ``achar`` converts a decimal ASCII code to a single character string.
 ::
+
   load system io.
   load system type.
   load system util.
@@ -257,6 +279,7 @@ In our solution we take advantage of Asteroid's ``Pick`` object.  The ``Pick`` o
 
   assert (pwd == "e3zvshdbS43brt#")
 
+
 Output::
 
     e3zvshdbS43brt#
@@ -277,6 +300,7 @@ to RNA happens according to the following table:
 
 We will solve this programming problem using Asteroid's first-class patterns. We could have solved this with just testing equality on DNA characters. However, using first-class patterns is more general and can be applied to problems with a more structured mapping relationship.
 ::
+
   load system io.
 
   let dna2rna_table =
@@ -304,6 +328,7 @@ We will solve this programming problem using Asteroid's first-class patterns. We
 
   assert(rna_seq == "UGGUAGUCAG").
 
+
 Output::
 
     UGGUAGUCAG
@@ -321,6 +346,7 @@ For example, if N is 4, then the letter e becomes a, f is transformed to b,
 etc. The alphabet is looped so that z becomes v, and letters a to d become
 w to z.
 ::
+
   load system io.
   load system util.
 
@@ -362,6 +388,7 @@ w to z.
 
   assert (decoded_msg == "hello, world!")
 
+
 Output::
 
     dahhk, sknhz!
@@ -382,12 +409,14 @@ In program outputs, it is often required to print some number followed by a noun
 
 If there is only one file, then the phrase should be ``1 file found`` instead.
 ::
+
   load system io.
 
   for n in 0 to 5 do
       io @println (n+" file"+("s " if n>1 or n==0 else " ")+"found").
   end
 
+
 Output::
 
     0 files found
@@ -406,6 +435,7 @@ Challenge: The most frequent word
 In our solution we use a hash table to count the number of word occurences.
 ::
 
+
   load system io.
   load system util.
   load system hash.
@@ -464,6 +494,7 @@ In our solution we use a hash table to count the number of word occurences.
 
   assert (most_frequent_word == "sed").
 
+
 Output::
 
     sed
@@ -480,6 +511,7 @@ There are two loops (see also Task 17, The longest palindrome) over the first
 string (``stra``). These use the index method to search for the substring in the
 second string (``strb``).
 ::
+
   load system io.
 
   let stra = "the quick brown fox jumps over the lazy dog".
@@ -503,6 +535,7 @@ second string (``strb``).
 
   assert (common == " fox ").
 
+
 Output::
 
     The longest common substring is ' fox '.
@@ -515,6 +548,7 @@ Challenge: Anagram test
 
 An anagram is a word, phrase, or name formed by rearranging the letters of another, such as ``cinema``, formed from ``iceman``.
 ::
+
   load system io.
 
   let str1 = "cinema".
@@ -534,6 +568,7 @@ An anagram is a word, phrase, or name formed by rearranging the letters of anoth
 
   assert (normalize(str1) == normalize(str2)).
 
+
 Output::
 
     Anagrams
@@ -547,6 +582,7 @@ Challenge: Palindrome test
 A palindrome is a string that can be read from both ends: left to right or right
 to left.
 ::
+
   load system io.
 
   let str = "Was it a rat I saw?".
@@ -568,6 +604,7 @@ to left.
 
   assert (clean_str == clean_str @flip()).
 
+
 Output::
 
     Palindromic
@@ -586,6 +623,7 @@ Now, extract the substring and do the check similar to the solution of Task
 without taking into account the non-letter characters, but saving the result as
 part of the original string.
 ::
+
   load system io.
 
   let str = "Hello, World!".
@@ -619,6 +657,7 @@ part of the original string.
 
   io @println longest_palindrome.
 
+
 Output::
 
     o, Wo
@@ -631,6 +670,7 @@ Challenge: Finding duplicate texts
 
 We do this by finding and hashing N-grams after the appropriate preprocessing.  We will use ``N=3``.
 ::
+
   load system io.
   load system hash.
 
@@ -748,6 +788,7 @@ We do this by finding and hashing N-grams after the appropriate preprocessing.
       io @println (n_gram+": "+cnt).
   end
 
+
 Output::
 
     lorem ipsum dolor: 2
@@ -773,17 +814,20 @@ Challenge: Pi
 
 > Print the value of pi.
 ::
+
   load system io.
   load system math. -- definition of pi
 
   io @println (math @pi).
 
+
 Output::
 
     3.141592653589793
 
 Other constants are also available.
 ::
+
   load system io.
   load system math.
 
@@ -792,6 +836,7 @@ Other constants are also available.
 
   assert (math @tau == 2 * math @pi)
 
+
 Output::
 
     2.718281828459045
@@ -805,6 +850,7 @@ Challenge: Factorial!
 
 By definition, the factorial of a positive integer number N is a product of all the integers numbering from 1 to N, including N. Our first solution is based on the direct implementation of the definition above using the list ``reduce`` function.
 ::
+
   load system io.
 
   let n = 3.
@@ -812,6 +858,7 @@ By definition, the factorial of a positive integer number N is a product of all
   io @println fact.
   assert (fact == 6).
 
+
 Output::
 
     6
@@ -828,6 +875,7 @@ where :math:`x \in Int`.
 Here, each case specifies what value the function should return if
 the predicate applied to the input is true.  The last case is of some interest because it states that the function is undefined for negative integers.
 ::
+
   load system io.
 
   let POS_INT = pattern with (x:%integer) if x > 0.
@@ -845,6 +893,7 @@ the predicate applied to the input is true.  The last case is of some interest b
   io @println ("The factorial of 3 is: " + fact (3)).
   assert (fact(3) == 6).
 
+
 Output::
 
     The factorial of 3 is: 6
@@ -864,6 +913,7 @@ You can assign two values at a time (**Challenge: Swap two values**). You can us
 
 Here we give an iterative solutions.  It is clear that there exists a trivial recursive solution by implementing the above formula.
 ::
+
   load system io.
 
   let n = 10. -- compute the 10th Fib number
@@ -876,6 +926,7 @@ Here we give an iterative solutions.  It is clear that there exists a trivial re
   io @println f_1.
   assert (f_1 == 55)
 
+
 Output::
 
     55
@@ -888,6 +939,7 @@ Challenge: Print squares
 
 Of course this is straightforward, with a ``for-loop`` over a list.  Here we show another solution using the list ``map`` function.
 ::
+
   load system io.
 
   let sq = [1 to 10] @map(lambda with x do return x*x).
@@ -896,6 +948,7 @@ Of course this is straightforward, with a ``for-loop`` over a list.  Here we sho
 
   assert (sq == [1,4,9,16,25,36,49,64,81,100])
 
+
 Output::
 
     [1,4,9,16,25,36,49,64,81,100]
@@ -908,6 +961,7 @@ Challenge: Powers of two
 
 Just as in the previous challenge, we skip the naive loop solution and give a solution using the ``map`` function.
 ::
+
   load system io.
   load system math.
 
@@ -917,6 +971,7 @@ Just as in the previous challenge, we skip the naive loop solution and give a so
 
   assert (p2 == [1,2,4,8,16,32,64,128,256,512])
 
+
 Output::
 
     [1,2,4,8,16,32,64,128,256,512]
@@ -929,6 +984,7 @@ Challenge: Odd and even numbers
 
 We start with printing the first ten odd numbers,
 ::
+
   load system io.
   load system math.
 
@@ -940,6 +996,7 @@ We start with printing the first ten odd numbers,
   io @println odd.
   assert(odd == [1,3,5,7,9])
 
+
 Output::
 
     [1,3,5,7,9]
@@ -947,6 +1004,7 @@ Output::
 
 Now the even numbers,
 ::
+
   load system io.
   load system math.
 
@@ -958,6 +1016,7 @@ Now the even numbers,
   io @println even.
   assert(even == [2,4,6,8,10])
 
+
 Output:
 ::
 
@@ -971,6 +1030,7 @@ Challenge: Compare numbers approximately
 
 Comparing non-integer numbers (which are represented as floating-point numbers) is often a task that requires approximate comparison.  In Asteroid this can be accomplished with the ``isclose`` function availabel in the ``math`` module.
 ::
+
   load system io.
   load system math.
 
@@ -981,6 +1041,7 @@ Comparing non-integer numbers (which are represented as floating-point numbers)
   assert (math @isclose(2.0,2.00001,0.0001)).
 
 
+
 Challenge: Prime numbers
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -988,6 +1049,7 @@ Challenge: Prime numbers
 
 Prime numbers are those that can be divided only by 1, and by themselves.
 ::
+
   load system io.
   load system math.
 
@@ -1010,6 +1072,7 @@ Prime numbers are those that can be divided only by 1, and by themselves.
   assert (isprime(17)).
   assert (not isprime(15)).
 
+
 Output:
 ::
 
@@ -1022,6 +1085,7 @@ Challenge: List of prime numbers
 
 > Print the list of the first ten prime numbers.
 ::
+
   load system io.
   load system math.
 
@@ -1047,6 +1111,7 @@ Challenge: List of prime numbers
       end
   end
 
+
 Output:
 ::
 
@@ -1069,6 +1134,7 @@ Challenge: Prime factors
 
 Prime factors are the prime numbers that divide the given integer number exactly.
 ::
+
   load system io.
   load system math.
 
@@ -1111,6 +1177,7 @@ Prime factors are the prime numbers that divide the given integer number exactly
 
   assert (factors == [3,5,11])
 
+
 Output:
 ::
 
@@ -1124,6 +1191,7 @@ Challenge: Reducing a fraction
 
 5/15 and 16/280 are examples of fractions that can be reduced. The final results of this task are 1/3 and 2/35. Generally, the algorithm of reducing a fraction requires searching for the greatest common divisor, and then dividing both numerator and denominator by that number.  For our solution we use the function ``gcd`` available in the ``math`` module.
 ::
+
   load system io.
   load system math.
 
@@ -1141,6 +1209,7 @@ Challenge: Reducing a fraction
   -- show that original and reduced fraction are the same value
   assert (a/b == numerator/denominator).
 
+
 Output:
 ::
 
@@ -1155,6 +1224,7 @@ Challenge: Divide by zero
 
 Asteroid is an eager language, that is, expressions are evaluated as early as possible.  We can trap division-by-zero errors using a try-catch block.
 ::
+
   load system io.
 
   try
@@ -1164,6 +1234,7 @@ Asteroid is an eager language, that is, expressions are evaluated as early as po
   end
   io @println "We are still alive...".
 
+
 Output:
 ::
 
@@ -1181,6 +1252,7 @@ Challenge: Generating random numbers
 
 Asteroid has two random number generation functions: ``random()`` generates a random real value in the interval $[0.0,1.0)$ and ``randint(a,b)`` that generates a random value in the interval $[a,b]$.  The type of the random value generated depends on the type of the values a and b specifying the interval.
 ::
+
   load system io.
   load system random.
   load system util.
@@ -1199,6 +1271,7 @@ Asteroid has two random number generation functions: ``random()`` generates a ra
   io @println (randint(0.0,type @toreal(n))).
   io @println (randint(0,n)).
 
+
 Output:
 ::
 
@@ -1224,6 +1297,7 @@ This algorithm is a simple method of generating short sequences of four-digit ra
 
 To illustrate it with an example, let’s take the number 1234 as the seed. On step 2, it becomes 1522756; after step 3, 01522756. Finally, step 4 extracts the number 5227.
 ::
+
   load system io.
   load system util.
   load system type.
@@ -1242,6 +1316,7 @@ To illustrate it with an example, let’s take the number 1234 as the seed. On s
 
   assert (rval == 5227)
 
+
 Output:
 ::
 
@@ -1257,6 +1332,7 @@ The quality of the built-in generator of random numbers fully depends on the alg
 
 In our solution, we generate 10 random integers between 0 and 9. We then count how many times each of the integers have been generated.  If it is a decent random number generator, all numbers should have been generated roughly an equal number of times.
 ::
+
   load system io.
   load system random.
 
@@ -1269,6 +1345,7 @@ In our solution, we generate 10 random integers between 0 and 9. We then count h
 
   io @println hist.
 
+
 Output:
 ::
 
@@ -1286,6 +1363,7 @@ Challenge: Distance between two points
 There are two points on a surface, each with their own coordinates, x and y. The task is to find the distance between these two points.
 A straightforward solution would be to use the Pythagorean theorem:
 ::
+
   load system io.
   load system math.
 
@@ -1296,6 +1374,7 @@ A straightforward solution would be to use the Pythagorean theorem:
 
   assert (d == 2.23606797749979)
 
+
 Output:
 ::
 
@@ -1310,6 +1389,7 @@ Another approach is using the math identity,
 
 where ``.`` represents the dot product. In our case ``a`` would be the distance vector between points ``x`` and ``y``,
 ::
+
   load system io.
   load system math.
   load system vector.
@@ -1322,6 +1402,7 @@ where ``.`` represents the dot product. In our case ``a`` would be the distance
 
   assert (d == 2.23606797749979)
 
+
 Output:
 ::
 
@@ -1343,6 +1424,7 @@ Standard deviation is a statistical term that shows how compact data distributio
 
 where :math:`n` is the number of elements in the array :math:`x`; :math:`\bar{x}` is its average value (**Challenge: Average on an array**).
 ::
+
   load system io.
   load system math.
 
@@ -1357,6 +1439,7 @@ where :math:`n` is the number of elements in the array :math:`x`; :math:`\bar{x}
 
   assert (sigma == 420.96248961952256)
 
+
 Output:
 ::
 
@@ -1379,6 +1462,7 @@ The conversion formulae between the Cartesian and polar systems, which is valid
 
 These expressions can be implemented as-is in the code:
 ::
+
   load system io.
   load system math.
 
@@ -1409,6 +1493,7 @@ These expressions can be implemented as-is in the code:
   -- we started with
   assert (math @isclose(1,x,0.0001) and math @isclose(2,y,0.0001)).
 
+
 Output:
 ::
 
@@ -1419,6 +1504,7 @@ For the **negative** ``x`` and ``y``, the Cartesian-to-polar conversion is a bit
 or smaller than ``pi``. When ``x`` is zero, it is either ``-pi/2`` or ``pi/2``.
 All these variants can be implemented by using ``with`` clauses and conditional matching, as demonstrated below:
 ::
+
   load system io.
   load system math.
   load system util.
@@ -1467,6 +1553,7 @@ All these variants can be implemented by using ``with`` clauses and conditional
   -- we started with
   assert (math @isclose(-3,x,0.0001) and math @isclose(5,y,0.0001)).
 
+
 Output:
 ::
 
@@ -1482,6 +1569,7 @@ The Monte Carlo method is a statistical method of calculating data whose formula
 
 To calculate the area of a circle with a radius of 1, pairs of random numbers between −1 and 1 are generated. These pairs represent the points in the square in the center of coordinates with sides of length 2. The area of the square is thus 4. If the distance between the random point and the center of the square is less than 1, then this point is located inside the circle of that radius. Counting the number of points that landed inside the circle and the number of points outside the circle gives the approximate value of the area of the circle, as soon as the area of the square is known. Here is the program.
 ::
+
   load system io.
   load system math.
   load system random.
@@ -1505,6 +1593,7 @@ To calculate the area of a circle with a radius of 1, pairs of random numbers be
 
   assert (area == 3.1392).
 
+
 Output:
 ::
 
@@ -1519,6 +1608,7 @@ Challenge: Guess the number
 First, a random number needs to be generated. Then the program must
 ask for the initial guess and enter the loop, which compares the guess with the generated number.
 ::
+
   load system io.
   load system random.
   load system util.
@@ -1538,6 +1628,7 @@ ask for the initial guess and enter the loop, which compares the guess with the
   end
   io @println "Yes, this is it!".
 
+
 Challenge: Binary to integer
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1545,6 +1636,7 @@ Challenge: Binary to integer
 
 In Asteroid this is straightforward using the built-in ``tointeger`` function, passing it a string representation of the binary number and the base.
 ::
+
   load system io.
   load system type.
 
@@ -1554,6 +1646,7 @@ In Asteroid this is straightforward using the built-in ``tointeger`` function, p
 
   assert (int == 45).
 
+
 Output:
 ::
 
@@ -1567,6 +1660,7 @@ Challenge: Integer as binary, octal, and hex
 
 In Asteroid this is easily done with the ``tobase`` function.
 ::
+
   load system io.
   load system type.
 
@@ -1584,6 +1678,7 @@ In Asteroid this is easily done with the ``tobase`` function.
   assert (tointeger(tobase(val,8),8) == val).
   assert (tointeger(tobase(val,16),16) == val).
 
+
 Output:
 ::
 
@@ -1599,6 +1694,7 @@ Challenge: Sum of digits
 
 Pretty straightforward using string and list manipulation.
 ::
+
   load system io.
   load system type.
 
@@ -1612,6 +1708,7 @@ Pretty straightforward using string and list manipulation.
 
   assert (s == 49).
 
+
 Output:
 ::
 
@@ -1625,6 +1722,7 @@ Challenge: Bit counter
 
 If we remove all the zeros from a binary number, then we are left with only ``1`` characters which we can then count.
 ::
+
   load system io.
 
   let bits = "1010101" @replace("0","")
@@ -1633,6 +1731,7 @@ If we remove all the zeros from a binary number, then we are left with only ``1`
 
   assert (bits == 4).
 
+
 Output:
 ::
 
@@ -1646,6 +1745,7 @@ Challenge: Compose the largest number
 
 The easiest way to achieve that is to treat the numbers as strings, sort them alphabetically in descending order, concatenate the pieces to a single string, and get the resulting integer.
 ::
+
   load system io.
   load system type.
 
@@ -1654,6 +1754,7 @@ The easiest way to achieve that is to treat the numbers as strings, sort them al
 
   assert (a == 8675451).
 
+
 Output:
 ::
 
@@ -1671,6 +1772,7 @@ Let’s use the algorithm that keeps the table of pre-calculated sequences of Ro
 
 In the program below, there are four such sequences: for thousands, hundreds, tens, and ones. The program iterates over the digits of the number in the decimal representation and chooses one of the values from the array of lists stored in the ``roman_hash`` table.
 ::
+
   load system io.
   load system math.
   load system util.
@@ -1698,6 +1800,7 @@ In the program below, there are four such sequences: for thousands, hundreds, te
 
   assert (roman == "MMXVIII")
 
+
 Output:
 ::
 
@@ -1724,6 +1827,7 @@ For the larger numbers (21 to 99), there are two cases. If the number is dividab
 
 The zero name appears only in the case when the given number is zero.
 ::
+
   load system io.
   load system math.
 
@@ -1758,6 +1862,7 @@ The zero name appears only in the case when the given number is zero.
   io @println (spell_number 987654).
   io @println (spell_number 1001).
 
+
 Output:
 ::
 
@@ -1782,6 +1887,7 @@ In Asteroid, there is no need to use temporary variables to swap the values of t
 
 Consider the complete program:
 ::
+
   load system io.
 
   let (a,b) = (10,20).
@@ -1790,6 +1896,7 @@ Consider the complete program:
 
   assert ((a,b) is (20,10)).
 
+
 Output:
 ::
 
@@ -1803,6 +1910,7 @@ This program prints the swapped values:
 
 This approach also works with elements of an array:
 ::
+
   load system io.
 
   let a = [3,5,7,4].
@@ -1811,6 +1919,7 @@ This approach also works with elements of an array:
 
   assert (a is [3,5,4,7]).
 
+
 Output:
 ::
 
@@ -1822,6 +1931,7 @@ Challenge: Reverse a list
 
 > Print the given list in reverse order.
 ::
+
   load system io.
 
   let a = [10, 20, 30, 40, 50].
@@ -1829,6 +1939,7 @@ Challenge: Reverse a list
 
   assert(a == [50,40,30,20,10]).
 
+
 Output:
 ::
 
@@ -1842,6 +1953,7 @@ Challenge: Rotate a list
 
 Asteroid does not have a built-in ``rotate`` function. However, such a function is easily constructed through slicing lists (see ``vix`` below).
 ::
+
   load system io.
   load system math.
 
@@ -1861,6 +1973,7 @@ Asteroid does not have a built-in ``rotate`` function. However, such a function
 
   assert(b == [7,9,11,13,15,1,3,5] and c == [11,13,15,1,3,5,7,9]).
 
+
 Output:
 ::
 
@@ -1876,6 +1989,7 @@ Challenge: Randomize an array
 
 This is easily accomplished with the built-in ``shuffle``.
 ::
+
   load system io.
   load system random.
 
@@ -1885,6 +1999,7 @@ This is easily accomplished with the built-in ``shuffle``.
 
   assert(b == [20,6,15,5,10,14,16,19,7,13,18,11,2,12,3,17,8,9,1,4]).
 
+
 Output:
 ::
 
@@ -1898,6 +2013,7 @@ Challenge: Incrementing array elements
 
 For this we use Asteroid's ``vector`` module, which can handle incrementing a vector with a scalar.
 ::
+
   load system io.
   load system vector.
 
@@ -1907,6 +2023,7 @@ For this we use Asteroid's ``vector`` module, which can handle incrementing a ve
 
   assert(b == [2,3,4,5,6,7,8,9,10,11]).
 
+
 Output:
 ::
 
@@ -1920,6 +2037,7 @@ Challenge: Adding up two arrays
 
 Again, here we take advantage of Asteroid's ``vector`` module.  Note that the two vectors have to be of the same length in order to add them together.
 ::
+
   load system io.
   load system vector.
 
@@ -1930,6 +2048,7 @@ Again, here we take advantage of Asteroid's ``vector`` module.  Note that the tw
 
   assert(c == [40,42,44,46,48,50,52,54,56,58,60]).
 
+
 Output:
 ::
 
@@ -1938,6 +2057,7 @@ Output:
 
 The vector module defines a function called ``op`` that allows you to combine two vectors using any arbitrary binary function.  Rewriting the above program using ``op``,
 ::
+
   load system io.
   load system vector.
 
@@ -1948,6 +2068,7 @@ The vector module defines a function called ``op`` that allows you to combine tw
 
   assert(c == [40,42,44,46,48,50,52,54,56,58,60]).
 
+
 Output:
 ::
 
@@ -1956,6 +2077,7 @@ Output:
 
 As we said above, any arbitrary binary function. Consider the relational operator ``<`` expressed as a lambda function,
 ::
+
   load system io.
   load system vector.
   load system random.
@@ -1969,6 +2091,7 @@ As we said above, any arbitrary binary function. Consider the relational operato
 
   assert(c == [false,true,false,false,false,true,false,false,true,true]).
 
+
 Output:
 ::
 
@@ -1983,6 +2106,7 @@ appear in the second one.
 
 Here we use Asteroid's ``set`` module.
 ::
+
   load system io.
   load system set.
 
@@ -1993,6 +2117,7 @@ Here we use Asteroid's ``set`` module.
 
   assert(c @sort() == [1,2,3,4]).
 
+
 Output:
 ::
 
@@ -2007,6 +2132,7 @@ Challenge: Sum of the elements of an array
 
 > Find the sum of the elements of an array of integers.
 ::
+
   load system io.
 
   let a = [4, 6, 8, 1, 0, 58, 1, 34, 7, 4, 2].
@@ -2015,6 +2141,7 @@ Challenge: Sum of the elements of an array
 
   assert (s == 125).
 
+
 Output:
 ::
 
@@ -2023,6 +2150,7 @@ Output:
 
 If summing up elements that are greater than 10,
 ::
+
   load system io.
 
   let a = [4, 6, 8, 1, 0, 58, 1, 34, 7, 4, 2].
@@ -2032,6 +2160,7 @@ If summing up elements that are greater than 10,
 
   assert (s == 92).
 
+
 Output:
 ::
 
@@ -2043,6 +2172,7 @@ Challenge: Average of an array
 
 > Find the average value of the given array of numbers.
 ::
+
   load system io.
 
   let a = [7, 11, 34, 50, 200].
@@ -2051,6 +2181,7 @@ Challenge: Average of an array
 
   assert (avg == 60).
 
+
 Output:
 ::
 
@@ -2062,12 +2193,14 @@ Challenge: Is an element in a list?
 
 > Tell if the given value is in the list.
 ::
+
   load system io.
 
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
   let x = 17.
   io @println ((x+" is in the list") if array @member(x) else (x+" is not in the list")).
 
+
 Output:
 ::
 
@@ -2076,6 +2209,7 @@ Output:
 
 We can also use a reduction function to solve this,
 ::
+
   load system io.
 
   let array = [10, 14, 0, 15, 17, 20, 30, 35].
@@ -2087,6 +2221,7 @@ We can also use a reduction function to solve this,
       io @println (x+" is not in the list").
   end
 
+
 Output:
 ::
 
@@ -2100,6 +2235,7 @@ Challenge: First odd number
 
 The easiest way to do this is with a reduction,
 ::
+
   load system io.
   load system math.
   load system util.
@@ -2111,6 +2247,7 @@ The easiest way to do this is with a reduction,
   let odd = array @reduce(lambda with (acc,i) do return i if type @isnone(acc) and mod(i,2) else acc,none).
   io @println odd.
 
+
 Output:
 ::
 
@@ -2122,6 +2259,7 @@ Challenge: Take every second element
 
 > Form a new array by picking every second element from the original array.
 ::
+
   load system io.
   load system math.
 
@@ -2130,6 +2268,7 @@ Challenge: Take every second element
 
   assert (array == [21,23,25,27,29]).
 
+
 Output:
 ::
 
@@ -2138,6 +2277,7 @@ Output:
 
 We can use an index vector to accomplish  the same thing,
 ::
+
   load system io.
   load system math.
 
@@ -2147,6 +2287,7 @@ We can use an index vector to accomplish  the same thing,
 
   assert (array == [21,23,25,27,29]).
 
+
 Output:
 ::
 
@@ -2158,6 +2299,7 @@ Challenge: Number of occurrences in an array
 
 > Count how many times a particular element appears in the array.
 ::
+
   load system io.
   load system math.
 
@@ -2177,6 +2319,7 @@ Challenge: Number of occurrences in an array
 
   assert (cnt == 2).
 
+
 Output:
 ::
 
@@ -2190,6 +2333,7 @@ Challenge: Finding unique elements
 
 Converting a list to a set will remove all duplicate elements in the list.
 ::
+
   load system io.
   load system set.
 
@@ -2203,6 +2347,7 @@ Converting a list to a set will remove all duplicate elements in the list.
 
   assert (a == [2,3,4,5,6,7,10])
 
+
 Output:
 ::
 
@@ -2214,6 +2359,7 @@ Challenge: Minimum and maximum
 
 > Find the minimum and the maximum numbers in the given list of integers.
 ::
+
   load system io.
 
   function max with lst:%list do
@@ -2234,6 +2380,7 @@ Challenge: Minimum and maximum
 
   assert (a == 15 and b == 2).
 
+
 Output:
 ::
 
@@ -2246,6 +2393,7 @@ Challenge: Increasing sequences
 
 > Check if the given array contains increasing (or decreasing) numbers.
 ::
+
   load system io.
   load system type.
 
@@ -2256,6 +2404,7 @@ Challenge: Increasing sequences
 
   assert (b).
 
+
 Output:
 ::
 
@@ -2296,6 +2445,7 @@ with its transpose,
 
 The procedure:
 ::
+
   load system io.
 
   function transpose with m do
@@ -2356,6 +2506,7 @@ The procedure:
 
   assert(mt == [[1,3,5],[2,4,6]]).
 
+
 Output:
 ::
 
@@ -2389,6 +2540,7 @@ Challenge: Sort hashes by parameter
 
 This task is commonly performed to sort items where the sortable parameter is one of the values in the hash. For example, sorting a list of people by age.
 ::
+
   load system io.
   load system hash.
   load system sort.
@@ -2420,6 +2572,7 @@ This task is commonly performed to sort items where the sortable parameter is on
 
   assert (sort @sort(pairs,lst) == [("Pete",20),("Joe",23),("Billie",40),("Brandi",43)])
 
+
 Output:
 ::
 
@@ -2433,6 +2586,7 @@ Challenge: Count hash values
 
 For example, a hash is a collection mapping a car’s license plate to the colour of the car or a passport number to the name of the street where the person lives. In the first example, the task is to count how many cars of each colour there are. In the second example, we have to say how many people live on each street. But let’s simply count the colours of fruit.
 ::
+
   load system io.
   load system hash.
   load system sort.
@@ -2467,6 +2621,7 @@ For example, a hash is a collection mapping a car’s license plate to the colou
 
   io @println (sort @sort(pairs,color_lst)).
 
+
 Output:
 ::
 
@@ -2480,6 +2635,7 @@ Challenge: Product table
 
 We will do this with an outer loop  and a ``map`` function.
 ::
+
   load system io.
   load system type.
 
@@ -2493,6 +2649,7 @@ We will do this with an outer loop  and a ``map`` function.
       io @println ([1 to 10] @map(lambda with x do return format(i*x)) @join(" ")).
   end
 
+
 Output:
 ::
 
@@ -2555,6 +2712,7 @@ We then add them together,
 
 The only thing that is left to do is to iterate appropiately and format the output.
 ::
+
   load system io.
   load system vector.
   load system util.
@@ -2576,6 +2734,7 @@ The only thing that is left to do is to iterate appropiately and format the outp
       io @println (r @map(lambda with v do return type @tostring v) @join(" ")).
   end
 
+
 Output:
 ::
 
@@ -2590,3 +2749,4 @@ Output:
 
 The program prints the first seven rows of the Pascal triangle. The rows are not centred, and are aligned to the left side.
 As an extra exercise, modify the program so that it prints the triangle as it is shown at the beginning of this task. For example, you can first generate rows and keep them in a separate array and then, knowing the length of the longest string, add some spaces in front of the rows before printing them.
+
diff --git a/docs/Reference Guide.rst b/docs/Reference Guide.rst
index 2e427523..2e7b2671 100644
--- a/docs/Reference Guide.rst
+++ b/docs/Reference Guide.rst
@@ -2,19 +2,10 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
 ..
    *** DO NOT EDIT; MACHINE GENERATED ***
 
+
 .. highlight:: none
 
 Asteroid Reference Guide
@@ -32,6 +23,7 @@ where ``<syntactic unit>*`` means zero or more occurrences of the syntactic unit
 are written in quotes.
 ::
 
+
   ////////////////////////////////////////////////////////////////////////////////////////
   // statements
 
@@ -54,7 +46,6 @@ are written in quotes.
     | WHILE exp DO stmt_list END
     | REPEAT DO? stmt_list UNTIL exp '.'?
     | IF exp DO stmt_list (ELIF exp DO stmt_list)* (ELSE DO? stmt_list)? END
-    | MATCH exp WITH? (CASE pattern DO stmt_list)+ (OTHERWISE DO? stmt_list)? END
     | TRY DO? stmt_list (CATCH pattern DO stmt_list)+ END
     | THROW exp '.'?
     | BREAK '.'?
@@ -85,15 +76,11 @@ are written in quotes.
   ////////////////////////////////////////////////////////////////////////////////////////
   // expressions/patterns
   
-  pattern
-    : exp
-
   exp
-    : quote_exp
+    : pattern
 
-  quote_exp
-    : QUOTE exp
-    | PATTERN WITH? exp
+  pattern
+    : PATTERN WITH? exp
     | '%[' exp ']%'      
     | head_tail
 
@@ -167,6 +154,7 @@ are written in quotes.
     : LAMBDA body_defs
 
 
+
 Builtin Functions
 -----------------
 
@@ -389,12 +377,14 @@ The `math <https://github.com/asteroid-lang/asteroid/blob/master/asteroid/module
 
 An example,
 ::
+
     load system io.
     load system math.
 
     let x = math @sin( math @pi / 2 ).
     io @println("The sine of pi / 2 is " + x + ".").
 
+
 Pick
 ^^^^
 
@@ -403,6 +393,7 @@ pick objects that allow a user to randomly pick items from a list using the ``pi
 The ``pick`` function can be called with ``n:%integer`` and returns a list of ``n`` randomly picked objects from the object list.
 Here is a simple use case
 ::
+
    load system io.
    load system pick.
 
@@ -446,12 +437,14 @@ The ``sort`` function makes use of a user-defined order predicate on the list's
 perform the sort. The ``Quicksort`` is the underlying sort algorithm.
 The following is a simple example,
 ::
+
    load system io.
    load system sort.
    let sl = sort @sort((lambda with (x,y) do return true if x<y else false),
                        [10,5,110,50]).
     io @println sl.
 
+
 prints the sorted list::
 
   [5,10,50,110]
@@ -473,6 +466,7 @@ The following stream interface functions are available,
 
 A simple use case.
 ::
+
    load system io.
    load system stream.
 
@@ -515,6 +509,7 @@ The `type <https://github.com/asteroid-lang/asteroid/blob/master/asteroid/module
 
 Here is a program that exercises some of the string formatting options,
 ::
+
     load system io.
     load system type.
     load system math.
@@ -536,6 +531,7 @@ Here is a program that exercises some of the string formatting options,
     let r = type @tostring(math @pi,type @stringformat(6,3)).
     io @println r.
 
+
 The output of the program is,
 ::
 
@@ -556,6 +552,7 @@ Notice the right justification of the various values within the given string len
 
 A simple example program using the ``gettype`` function,
 ::
+
    load system type.
 
    let i = 1.
@@ -597,6 +594,7 @@ The `vector <https://github.com/asteroid-lang/asteroid/blob/master/asteroid/modu
 
 Here is a simple example program for the ``vector`` module,
 ::
+
    load system io.
    load system vector.
 
@@ -607,3 +605,4 @@ Here is a simple example program for the ``vector`` module,
    
 
 which prints the value ``0``.
+
diff --git a/docs/User Guide.rst b/docs/User Guide.rst
index 7ca977cc..389dc050 100644
--- a/docs/User Guide.rst
+++ b/docs/User Guide.rst
@@ -10,11 +10,10 @@
 
 
 
-
-
 ..
    *** DO NOT EDIT; MACHINE GENERATED ***
 
+
 .. highlight:: none
 
 Asteroid User Guide
@@ -32,12 +31,16 @@ paradigm.  Here are just two examples:
 
 **Example:** All statements that look like assignments are actually pattern-match statements.  For example if we state,
 ::
+
     let [x,2,y] = [1,2,3].
 
+
 that means the subject term ``[1,2,3]`` is matched to the pattern ``[x,2,y]`` and ``x`` and ``y`` are bound to the values 1 and 3, respectively.  By the way, there is nothing wrong with the following statement,
 ::
+
     let [1,2,3] = [1,2,3].
 
+
 which is just another pattern match without any variable instantiations.
 
 **Example:** Patterns in Asteroid are first-class citizens of the language.
@@ -45,6 +48,7 @@ This is best demonstrated with a program.  Here is a program
 that recursively computes the factorial of a positive integer and uses first-class patterns
 in order to ensure that the domain of the function is not violated,
 ::
+
     -- define first-class patterns
     let POS_INT = pattern (x:%integer) if x > 0.
     let NEG_INT = pattern (x:%integer) if x < 0.
@@ -59,6 +63,7 @@ in order to ensure that the domain of the function is not violated,
             throw Error("undefined for "+n).
         end
 
+
 As you can see, the program first creates patterns and stores them in the variables
 ``POS_INT`` and ``NEG_INT`` and it uses those patterns later in the code by
 dereferencing those variables with the ``*`` operator.  First-class patterns have
@@ -87,8 +92,10 @@ Asteroid arranges these data types in a **type hierarchy**,
 Type hierarchies facilitate automatic type promotion.  Here is an example
 where automatic type promotion is used to put together a string from different data types,
 ::
+
     let x:%string = "value: " + 1.
 
+
 Here we associate the string ``"value: 1"`` with the variable ``x`` by first promoting the integer value ``1`` to the string ``"1"`` using the fact that ``integer`` < ``string``  according to our type hierarchy  and then interpreting the ``+`` operator as a string concatenation operator.
 
 Asteroid supports two more data types:
@@ -99,13 +106,17 @@ Asteroid supports two more data types:
 These are **structured data types** in that they can contain entities of other data types. Both of these data types have the probably familiar constructors which are possibly empty squences of comma separated values enclosed by square brackets for lists, e.g. ``[1,2,3]``, and enclosed by parentheses for tuples, e.g. ``(x,y)``. For tuples we have the caveat that the 1-tuple is represented by a value followed by a comma to distinguish it from parenthesized expressions, e.g.``(3,)``.
 Here are some examples,
 ::
+
     let a = [1,2,3].  -- this is a list
     let c = (1,2,3).  -- this is a tuple
 
+
 As we said above, in order to distinguish it from a parenthesized value the single element in a 1-tuple has to be followed by a comma, like so,
 ::
+
     let one_tuple = (1,).  -- this is a 1-tuple
 
+
 Lists and tuples themselves are also embedded in type hierarchies, although very simple ones:
 
 * ``list`` < ``string``
@@ -113,16 +124,20 @@ Lists and tuples themselves are also embedded in type hierarchies, although very
 
 That is, any list or tuple can be viewed as a string.  This is very convenient for printing lists and tuples,
 ::
+
     load system io.
     io @println ("this is my list: " + [1,2,3]).
 
 
+
 Finally, Asteroid supports one more type, namely the ``none`` type.  The ``none`` type has
 only one member: A constant named conveniently ``none``.  The null-tuple belongs to this type (rather than the tuple type discussed earlier) and therefore the constant ``()`` can often be used as a convenient short hand for the constant ``none``.  That is, the following ``let`` statements will succeed,
 ::
+
     let none = ().
     let () = none.
 
+
 meaning that the constants ``()`` and ``none`` are equivalent and pattern-match each other.
 The ``none`` data type itself does not belong to any type hierarchy.
 
@@ -136,23 +151,27 @@ Lists
 
 In Asteroid the ``list`` is a fundamental, built-in data structure.  A trait it shares with programming languages such as Lisp, Python, ML, and Prolog.  Below is the list reversal example from above as an executable Asteroid program. So go ahead and experiment!
 ::
+
     load system io.    -- load the io module so we can print
 
     let a = [1,2,3].     -- construct list a
     let b = a @[2,1,0].  -- reverse list a
     io @println b.
 
+
 The output is: ``[3,2,1]``.
 
 In Asteroid lists are considered objects with member functions that can manipulate the list
 object, e.g. ``[1,2,3] @ reverse()``. We could rewrite the above example as,
 ::
+
     load system io.
 
     let a = [1,2,3].
     let b = a @reverse().
     io @println b.
 
+
 For a full list of available member functions for Asteroid lists please see the reference guide.
 
 As we have seen, the ``@`` operator allows you to access either individual elements, slices, or member functions of a list.
@@ -161,6 +180,7 @@ Besides using the default constructor for lists which consists of the
 square brackets enclosing a list of elements we can use **list comprehensions** to construct lists.  In Asteroid a list comprehension consist of a range specifier together with
 a stride specifier allowying you to generate integer values within that range,
 ::
+
     load system io.
 
     -- build a list of odd values
@@ -172,6 +192,7 @@ a stride specifier allowying you to generate integer values within that range,
     let b = a @slice.
     io @println ("reversed list: " + b).
 
+
 The output is,
 ::
 
@@ -182,6 +203,7 @@ Asteroid's simple list comprehensions in conjunction with the ``map`` function f
 construct virtually  any kind of list. For example, the following program constructs
 a list of alternating 1 and -1,
 ::
+
     load system io.
     load system math.
 
@@ -190,6 +212,7 @@ a list of alternating 1 and -1,
 
     io @println a.
 
+
 where the output is,
 ::
 
@@ -197,6 +220,7 @@ where the output is,
 
 Higher dimensional arrays can easily be simulated with lists of lists,
 ::
+
     load system io.
 
     -- build a 2-D array
@@ -208,6 +232,7 @@ Higher dimensional arrays can easily be simulated with lists of lists,
     let b @1 @1 = 0.
     io @println b.
 
+
 The output is: ``[[1,2,3],[4,0,6],[7,8,9]]``
 
 **NOTE**: At this point slicing is not supported on the left side of a ``let`` statement.
@@ -219,13 +244,16 @@ As we saw earlier, the ``tuple`` is another fundamental, built-in data structure
 
 Below is an example of a tuple declaration and access.
 ::
+
     load system io.   -- load the io module so we can print
     let a = (1,2,3).    -- construct tuple a
     let b = a @1.       -- access the second element in tuple a
     io @println b.          -- print the element to the console
 
+
 Like ``lists``, ``tuples`` may also be nested,
 ::
+
     load system io.
     -- build a 2-D array
     let b = (("a","b","c"),
@@ -234,8 +262,10 @@ Like ``lists``, ``tuples`` may also be nested,
     -- Access an element in the nested structure.
     io @println(b @1 @1).
 
+
 Unlike lists, tuples are immutable. This means that their contents cannot be changed once they have been declared. Should we want to change the contents of an already declared tuple, we would need to abandon the original and declare a new ``tuple``. The following code block demonstrates this,
 ::
+
     load system io.
     -- build a tuple
     let b = ("a","b","c").
@@ -246,6 +276,7 @@ Unlike lists, tuples are immutable. This means that their contents cannot be cha
         io @println(kind+": "+s).
     end.
 
+
 Which will print out the following message:
 ::
 
@@ -264,6 +295,7 @@ a *default constructor* for a structure.  That constructor copies the arguments
 data member fields of the structure in the order that the data members appear in the
 structure definition and as they appear in the parameter list of the constructor. Here is a simple example,
 ::
+
     load system io.
 
     structure Person with
@@ -284,6 +316,7 @@ structure definition and as they appear in the parameter list of the constructor
     let Person(name,age,gender) = people @1. -- pattern match against the structure
     io @println (name + " is " + age + " years old and is " +  gender + ".").
 
+
 The output is,
 ::
 
@@ -308,6 +341,7 @@ the ``=`` operator are completely legal and highlight the fact that ``let`` stat
 
 Here is an example where we do some computations on the right side of a ``let`` statement and then match the result against a pattern on the left,
 ::
+
     load system io.
 
     -- note 1+1 evaluates to 2 and is then matched
@@ -316,13 +350,16 @@ Here is an example where we do some computations on the right side of a ``let``
     let [x,2,y] = [1+0,1+1,1+2].
     io @println (x,y).
 
+
 The output is: ``(1,3)``
 
 Asteroid supports special patterns called **type patterns** that match any value
 of a given type.  For instance, the ``%integer`` pattern matches any integer value.  Here is a simple example,
 ::
+
     let %integer = 1.
 
+
 This ``let`` statement succeeds because the value ``1`` can be pattern matched against
 the type pattern ``%integer``
 
@@ -331,11 +368,13 @@ supports something called a **named pattern** were a (sub)pattern on the left si
 of a ``let`` statement (or any pattern as it appears in Asteroid) can be given a name
 and that name will be instantiated with a term during pattern matching.  For example,
 ::
+
     load system io.
 
     let t:(1,2) = (1,2).  -- using a named pattern on lhs
     io @println t.
 
+
 Here, the construct ``t:(1,2)`` is called a named pattern and the variable ``t`` will be unified with the term ``(1,2)``, or more generally, the variable will be unified with term
 that matches the pattern on the right of the colon.  The program will print,
 ::
@@ -346,6 +385,7 @@ We can combine type patterns and named patterns to give us something that looks
 like a variable declaration in other languages. In Asteroid, though, it is still just all
 about pattern matching.  Consider,
 ::
+
     load system io.
     load system math.
     load system type.
@@ -353,6 +393,7 @@ about pattern matching.  Consider,
     let x:%real = math @pi.
     io @println (type @tostring(x,type @stringformat(4,2))).
 
+
 The left side of the ``let`` statement is a named type pattern that matches any real value, and
 if that match is successful then the value is bound to the variable ``x``.  Note
 that even though this looks like a declaration, it is in fact a pattern matching
@@ -365,12 +406,14 @@ Control structure implementation in Asteroid is along the lines of any of the mo
 
 As we said, in terms of flow of control statements there are really not a lot of surprises. This is because Asteroid supports loops and conditionals in a very similar way to many of the other modern programming languages in use today.  For example, here is a short program with a ``for`` loop that prints out the first six even positive integers,
 ::
+
     load system io.
 
     for i in 0 to 10 stride 2 do
         io @println i.
     end
 
+
 The output is,
 ::
 
@@ -383,6 +426,7 @@ The output is,
 
 Here is another example that iterates over lists,
 ::
+
     load system io.
     load system util
 
@@ -390,6 +434,7 @@ Here is another example that iterates over lists,
         io @println ("the "+ix+" bird is a "+bird).
     end
 
+
 The output is,
 ::
 
@@ -402,6 +447,7 @@ iterate pattern matching on each of the pairs on the list with the pattern ``(ix
 
 The following is a short program that demonstrates an ``if`` statement,
 ::
+
     load system io.
     load system type.
 
@@ -418,6 +464,7 @@ The following is a short program that demonstrates an ``if`` statement,
         io @println("More").
     end
 
+
 Even though Asteroid's flow of control statements look so familiar, they support pattern matching to a degree not found in other programming languages and which we will take a look at below.
 
 Functions
@@ -431,6 +478,7 @@ instantiating the formal arguments.
 Let's start with something simple.  Here is a function definition for ``revdouble`` that reverses a list of integers
 then doubles each value before returning the result,
 ::
+
     load system io.
 
     function revdouble
@@ -440,6 +488,7 @@ then doubles each value before returning the result,
 
     io @println (revdouble [1,2,3]).
 
+
 The output is ``[6,4,2]``.  Notice how we used type patterns to make sure that this
 function is only applied to lists of integers.
 
@@ -447,6 +496,7 @@ In order to demonstrate functional programming like multi-dispatch, the followin
 Asteroid. Each ``with`` clause introduces a new function body with its
 corresponding pattern,
 ::
+
     load system io.
 
     function qsort
@@ -472,6 +522,7 @@ corresponding pattern,
     -- print the sorted list
     io @println (qsort [3,2,1,0])
 
+
 The output is as expected,
 ::
 
@@ -487,10 +538,12 @@ As you have seen in a couple of occasions already in the document, Asteroid also
 functions except that you declare them on-the-fly and they are declared without a
 name.  Here is an example using a ``lambda`` function,
 ::
+
     load system io.
 
     io @println ((lambda with n do return n+1) 1).
 
+
 The output is ``2``.  Here, the lambda function is a function that takes a value
 and increments it by one.  We then apply the value ``1`` to the function and the
 print function prints out the value ``2``.
@@ -506,6 +559,7 @@ Pattern Matching in Expressions: The ``is`` Predicate
 
 Consider the following example of this predicate among some patterns,
 ::
+
     load system io.
 
     let p = (1,2).
@@ -518,6 +572,7 @@ Consider the following example of this predicate among some patterns,
         io @println "it's something else".
     end
 
+
 Here we use patterns to determine if ``p`` is a triple, a pair, or something else. Pattern matching is embedded in the expressions of the ``if`` statement. The
 output of this program is,
 ::
@@ -540,6 +595,7 @@ We can also employ pattern matching in loops.
 In the following program we use the ``is`` predicate to test whether the list is empty or not
 while looping,
 ::
+
     load system io.
 
     let list = [1,2,3].
@@ -550,6 +606,7 @@ while looping,
         let list = tail.
     until list is [].
 
+
 The output is,
 ::
 
@@ -573,6 +630,7 @@ Here is an example that uses pattern matching on function arguments using custom
 Here ``x`` and ``y`` are variables, ``0`` represents the natural number with value zero, and ``s`` is the successor function.  In Peano arithmetic any natural number can be represented by the appropriate number of applications of the successor function to the natural number ``0``. Here is the program where we replaced the ``+`` operator with the
 ``add`` symbol,
 ::
+
     -- implements Peano addition on terms
     load system io.
 
@@ -597,6 +655,7 @@ Here ``x`` and ``y`` are variables, ``0`` represents the natural number with val
     -- add 2 3
     io @println (reduce(add(s(s(0)),s(s(s(0)))))).
 
+
 Our program defines the structure ``s`` to represent the successor function and the structure ``add`` to represent Peano addition. Next, it defines a function that uses pattern matching to identify the left sides of the two axioms.  If either pattern matches the input to the ``reduce`` function, it will activate the corresponding function body and rewrite the term recursively in an appropriate manner.  We have one additional pattern which matches if neither one of the Peano axiom patterns matches and terminates the recursion.  Finally,  on the last line, we use our ``reduce`` function to compute the Peano term for the addition of 2 + 3. As expected, the output of this program is,
 ::
 
@@ -613,6 +672,7 @@ input values to function bodies.  Consider the following definition of the
 ``factorial`` function where we use conditional pattern matching to control
 the kind of values that are being passed to a particular function body,
 ::
+
     load system io.
 
     function factorial
@@ -626,6 +686,7 @@ the kind of values that are being passed to a particular function body,
 
     io @println ("The factorial of 3 is: " + factorial 3).
 
+
 Here we see that first, we make sure that we are being passed integers and second,
 that the integers are positive using the appropriate conditions on the input values. If
 we are being passed a negative integer, then we throw an error.
@@ -639,6 +700,7 @@ example. This combines structural matching with regular expression matching
 in ``for`` loops
 that selects certain items from a list. Suppose we want to print out the names of persons that contain a lower case 'p',
 ::
+
     load system io.
 
     structure Person with
@@ -658,6 +720,7 @@ that selects certain items from a list. Suppose we want to print out the names o
         io @println name.
     end
 
+
 Here we pattern match the ``Person`` object in the ``for`` loop and then use a regular expression to see if the name of that person matches our requirement that it contains a lower case 'p'.  We can tag the pattern with a variable name, a named pattern, so that we can print out the name if the regular expression matches. The output is ``Sophie``.
 
 Pattern Matching in ``try-catch`` Statements
@@ -665,6 +728,7 @@ Pattern Matching in ``try-catch`` Statements
 
 Exception handling in Asteroid is very similar to exception handling in many of the other modern programming languages available today.  The example below shows an Asteroid program  that throws one of two exceptions depending on the randomly generated value ``i``,
 ::
+
     load system io.
     load system random.
     load system type.
@@ -690,6 +754,7 @@ Exception handling in Asteroid is very similar to exception handling in many of
         io @println("you loose with "+type @tostring(v,type @stringformat(4,2))).
     end
 
+
 The ``Head`` and ``Tail`` exceptions are handled by their corresponding ``catch`` statements, respectively.  In both cases the exception object is unpacked using pattern matching and the unpacked value is used in the appropriate message printed to the screen.
 
 It is worth noting that even though Asteroid has builtin exception objects such as ``Error``,
@@ -720,6 +785,7 @@ The right side of the ``let`` statement invokes the default constructor for the
 structure in order to create an instance stored in the variable ``scarlett``. We
 can access members of the instance,
 ::
+
     load system io.
 
     structure Person with
@@ -732,12 +798,14 @@ can access members of the instance,
     -- access the name field of the structure instance
     io @println (scarlett @name).
 
+
 Asteroid allows you to attach functions to structures.  In member functions
 the object identity of the instance is available through the ``this`` keyword.
 For example, we can
 extend our ``Person`` structure with the ``hello`` function that uses the ``name`` field
 of the instance,
 ::
+
     load system io.
 
     structure Person with
@@ -754,6 +822,7 @@ of the instance,
     -- call the member function
     scarlett @hello().
 
+
 This program will print out,
 ::
 
@@ -767,6 +836,7 @@ The only thing you need to keep in mind is that you **cannot** pattern match on
 function field.  From a pattern matching perspective, a structure consists only of
 data fields.  So even if we declare a structure like this,
 ::
+
     load system io.
 
     structure Person with
@@ -784,6 +854,7 @@ data fields.  So even if we declare a structure like this,
     let Person(name,age,_) = Person("Scarlett",28,"F").
     io @println (name+" is "+age+" years old").
 
+
 where the function ``hello`` is defined in the middle of the data fields,
 pattern matching simply ignores the function definition and pattern matches
 only on the data fields.  The output of the program is,
@@ -799,6 +870,7 @@ dog instance by calling the ``add_trick`` function.  Rather than using the defau
 constructor, we define a constructor for our instances with the ``__init__`` function.
 Here is the program listing for the example in Asteroid,
 ::
+
     load system io.
     load system type.
 
@@ -833,6 +905,7 @@ Here is the program listing for the example in Asteroid,
         io @println (name+" knows how to fetch").
     end
 
+
 After declaring the structure we instantiate two dogs, Fido and Buddy, and add
 tricks to their respective trick repertoires.  The last couple of lines
 of the program consist of a ``for`` loop over a list of our dogs.
@@ -932,6 +1005,7 @@ in many spots in a program.  If patterns are not first-class citizens the develo
 will have to retype the same patterns over and over again in the various different
 spots where the patterns occurs. Consider the following program snippet,
 ::
+
     function fact
         with 0 do
             return 1
@@ -950,10 +1024,12 @@ spots where the patterns occurs. Consider the following program snippet,
             return -1.
         end
 
+
 In order to write these two functions we had to repeat the almost identical pattern
 four times.  First-class patterns allow us to write the same two functions in a
 much more elegant way,
 ::
+
     let POS_INT = pattern (x:%integer) if x > 0.
     let NEG_INT = pattern (x:%integer) if x < 0.
 
@@ -975,6 +1051,7 @@ much more elegant way,
                 return -1.
             end
 
+
 The relevant patterns are now stored in the variables ``POS_INT`` and ``NEG_INT``
 which are then used in the function definitions.
 
@@ -992,6 +1069,7 @@ In order to use a pattern as a constructor we apply the ``eval`` function to it
 turns the pattern into a value from Asteroid's point of view which can then be used
 in computations.  For example,
 ::
+
     load system io.
     let P = pattern ([a],[b]).
     let a = 1.
@@ -999,6 +1077,7 @@ in computations.  For example,
     let v = eval P. -- use pattern to construct a value
     io @println v.
 
+
 The output of the program is,
 ::
 
@@ -1009,6 +1088,7 @@ the variables ``a`` and ``b``, and
 the first-class pattern ``P``.  Of course, first-class patterns can be used
 to destructure the constructed value,
 ::
+
     load system io.
     let P = pattern ([a],[b]).
     let v = ([1],[2]).
@@ -1016,6 +1096,7 @@ to destructure the constructed value,
     io @println a.
     io @println b.
 
+
 As expected, the output is,
 ::
 
@@ -1031,6 +1112,7 @@ uses the first-class pattern ``FP`` to both construct an object network represen
 a family and, since it is a pattern, can also be used to destructure a family object
 network.  Here is the program listing,
 ::
+
     load system io.
 
     -----------------------------
@@ -1104,6 +1186,7 @@ network.  Here is the program listing,
     io @println (destructure_family (FP,f1)).
     io @println (destructure_family (FP,f2)).
 
+
 The function ``construct_family`` constructs a family evaluating the pattern using
 the ``eval`` function.  The formal parameters of the function provide values for
 the free variables in the pattern.  Since we are dealing with first-class
@@ -1149,6 +1232,7 @@ into the current environment.
 The most common use of constraint patterns is the prevention of non-linear patterns
 in functions.  Consider the following program,
 ::
+
    load system io.
 
    let POS_INT = pattern %[v if (v is %integer) and v > 0]%.
@@ -1180,6 +1264,7 @@ In order to demonstrate this type of multi-dispatch, we show the example program
 `multi-dispatch Wikipedia page <https://en.wikipedia.org/wiki/Multiple_dispatch>`_
 written in Asteroid,
 ::
+
     load system io.
     load system type.
 
@@ -1227,6 +1312,7 @@ written in Asteroid,
     io @println (collide(Asteroid(10), Spaceship(10))).
     io @println (collide(Spaceship(101), Spaceship(10))).
 
+
 Each ``with`` clause in the function ``collide_with`` introduces a new function body with its
 corresponding pattern.
 The function bodies in this case are simple ``return`` statements
@@ -1271,6 +1357,7 @@ The ``kind`` field will be populated by Asteroid with one of the following strin
 In addition to the ``kind`` field, the ``value`` field holds a string with some further details on the exception. Specific exceptions can be caught by pattern matching on the ``kind`` field of the ``Exception`` object.  For
 example,
 ::
+
     load system io.
 
     try
@@ -1279,6 +1366,7 @@ example,
         io @println s.
     end
 
+
 The output is,
 ::
 
@@ -1287,6 +1375,7 @@ The output is,
 
 Asteroid also provides a predefined ``Error`` object for user level exceptions,
 ::
+
     load system io.
 
     try
@@ -1295,9 +1384,11 @@ Asteroid also provides a predefined ``Error`` object for user level exceptions,
         io @println s.
     end
 
+
 Of course the user can also use the ``Exception`` object for their own exceptions
 by defining a ``kind`` that does not interfere with the predefined ``kind`` strings above,
 ::
+
     load system io.
 
     try
@@ -1306,6 +1397,7 @@ by defining a ``kind`` that does not interfere with the predefined ``kind`` stri
         io @println s.
     end
 
+
 The output here is,
 ::
 
@@ -1314,6 +1406,7 @@ The output here is,
 In addition to the Asteroid defined exceptions,
 the user is allowed to construct user level exceptions with any kind of object including tuples and lists. Here is an example that constructs a tuple as an exception object,
 ::
+
     load system io.
 
     try
@@ -1322,11 +1415,13 @@ the user is allowed to construct user level exceptions with any kind of object i
         io @println v.
     end
 
+
 The output of this program is ``42``.
 
 Now, if you don't care what kind of exception you catch, you need to use a ``wildcard`` or a variable because exception handlers are activated via pattern matching on the
 exception object itself.  Here is an example using a ``wildcard``,
 ::
+
     load system io.
 
     try
@@ -1335,8 +1430,10 @@ exception object itself.  Here is an example using a ``wildcard``,
         io @println "something happened".
     end
 
+
 Here is an example using a variable,
 ::
+
     load system io.
     load system type.
 
@@ -1346,6 +1443,7 @@ Here is an example using a variable,
         io @println ("something happened: "+type @tostring(e)).
     end
 
+
 In this last example we simply convert the caught exception object into a string
 and print it,
 ::
@@ -1358,12 +1456,14 @@ Basic Asteroid I/O
 
 I/O functions are defined as member functions of the ``io`` module. The ``println`` function prints its argument in a readable form to the terminal.  Recall that the ``+`` operator also implements string concatenation.  This allows us to construct nicely formatted output strings,
 ::
+
     load system io.
 
     let a = 1.
     let b = 2.
     io @println ("a + b = " + (a + b)).
 
+
 The output is
 ::
 
@@ -1379,6 +1479,7 @@ The width specifier tells the ``tostring`` function how many characters to reser
 
 Here is a program that exercises some of the string formatting options,
 ::
+
     load system io.
     load system type.
     load system math.
@@ -1400,6 +1501,7 @@ Here is a program that exercises some of the string formatting options,
     let r = type @tostring(math @pi,type @stringformat(6,3)).
     io @println r.
 
+
 The output of the program is,
 ::
 
@@ -1415,11 +1517,13 @@ except that it does not terminate print with a newline.
 
 Another useful function defined in the ``io`` module is the ``input`` function that, given an optional prompt string, will prompt the user at the terminal and return the input value as a string.  Here is a small example,
 ::
+
     load system io.
 
     let name = io @input("What is your name? ").
     io @println ("Hello " + name + "!").
 
+
 The output is,
 ::
 
@@ -1430,6 +1534,7 @@ The output is,
 We can use the type casting functions such as ``tointeger`` or ``toreal`` defined in the
 ``type`` module to convert the string returned from ``input`` into a numeric value,
 ::
+
     load system io.
     load system type.
 
@@ -1439,6 +1544,7 @@ We can use the type casting functions such as ``tointeger`` or ``toreal`` define
         io @println k.
     end
 
+
 The output is,
 ::
 
@@ -1476,11 +1582,14 @@ rather than in user directories.
 
 Say that you wanted to load the ``math`` module so you could execute a certain trigonometric function. The following Asteroid program loads the ``math`` module as well as the ``io``  module. Only after loading them would you be able to complete the sine function below,
 ::
+
     load system io.
     load system math.
 
     let x = math @sin( math @pi / 2 ).
     io @println("The sine of pi / 2 is " + x + ".").
 
+
 Both the function ``sin`` and the constant value ``pi`` are defined in the ``math`` module.
 In addition, the ``io`` module is where all input/output functions in Asteroid (such as ``println``) come from.
+


Test patch:
diff --git a/asteroid/test-suites/regression-tests/test014.ast b/asteroid/test-suites/regression-tests/test014.ast
index 9a24ecdf..cfa5a679 100644
--- a/asteroid/test-suites/regression-tests/test014.ast
+++ b/asteroid/test-suites/regression-tests/test014.ast
@@ -2,7 +2,7 @@
 load system io.
 
 try
-    let (1,y) = '(1,x).
+    let (1,y) = pattern (1,x).
 catch e do
     io @println e.
 end
diff --git a/asteroid/test-suites/regression-tests/test048.ast b/asteroid/test-suites/regression-tests/test048.ast
deleted file mode 100644
index 640c8c3d..00000000
--- a/asteroid/test-suites/regression-tests/test048.ast
+++ /dev/null
@@ -1,10 +0,0 @@
-
-load system io.
-load "util".
-
-let inc = (lambda with n do return n+1).
-
-
-io @println (eval ('inc 1)).
-
-assert(eval ('inc 1) is 2).
diff --git a/asteroid/test-suites/regression-tests/test054.ast b/asteroid/test-suites/regression-tests/test054.ast
deleted file mode 100644
index de4e6383..00000000
--- a/asteroid/test-suites/regression-tests/test054.ast
+++ /dev/null
@@ -1,35 +0,0 @@
-
--- implements Peano addition using a lookup table for the rewrite rules
-
-load "util".
-load system io.
-
-structure S with
-    data x.
-    end 
-    
-structure add with
-    data left.
-    data right.
-    end .
-
-let rule_table = [
-    ('add(x,0), 'reduce(x)),
-    ('add(x,S(y)), 'S(reduce(add(x,y))))
-    ].
-
-function reduce 
-    with term do
-        for i in 0 to rule_table @length()-1 do
-            -- limit visibility of free variables of the rewrite rules
-            -- to the with block scope
-            let (lhs, rhs) = rule_table@i.
-            if term is *lhs do
-                return eval rhs.
-            end 
-        end 
-        return term.
-    end 
-
-io @println (reduce('add(S(S(0)),S(S(S(0)))))).
-assert (reduce('add(S(S(0)),S(S(S(0))))) is S(S(S(S(S(0)))))).
diff --git a/asteroid/test-suites/regression-tests/test056.ast b/asteroid/test-suites/regression-tests/test056.ast
deleted file mode 100644
index d60181c0..00000000
--- a/asteroid/test-suites/regression-tests/test056.ast
+++ /dev/null
@@ -1,11 +0,0 @@
-
-load system io.
-load "util".
-
-function match
-    with (subject, p) do
-        return subject is *p.
-    end 
-    
-io @println (match('1+1, '_+_)).
-assert (match('1+1, '_+_) is true).
diff --git a/asteroid/test-suites/regression-tests/test062.ast b/asteroid/test-suites/regression-tests/test062.ast
deleted file mode 100644
index a1de512f..00000000
--- a/asteroid/test-suites/regression-tests/test062.ast
+++ /dev/null
@@ -1,7 +0,0 @@
-
-load system io.
-load "util".
-
-let true = ('1 + 2) is x + y.
-io @println (x,y).
-assert ((x,y) is (1,2)).
diff --git a/asteroid/test-suites/regression-tests/test069.ast b/asteroid/test-suites/regression-tests/test069.ast
deleted file mode 100644
index bb10c4a4..00000000
--- a/asteroid/test-suites/regression-tests/test069.ast
+++ /dev/null
@@ -1,16 +0,0 @@
-
-load "util".
-load system io.
-
-structure S with
-    data x.
-    end 
-    
-let x = 'S(S(0)).
-let y = 'S(S(x)).
-let z = y.
-
-io @println y.
-io @println z.
-io @println (eval (z)).
-assert ((eval (z)) is S(S(S(S(0))))).
diff --git a/asteroid/test-suites/regression-tests/test099.ast b/asteroid/test-suites/regression-tests/test099.ast
deleted file mode 100644
index ee74d30d..00000000
--- a/asteroid/test-suites/regression-tests/test099.ast
+++ /dev/null
@@ -1,5 +0,0 @@
-
-load system io.
-
-let v = 'a@[3].
-io @__raw_print__ v.
diff --git a/asteroid/test-suites/regression-tests/test119.ast b/asteroid/test-suites/regression-tests/test119.ast
index 0b391115..f46c953c 100644
--- a/asteroid/test-suites/regression-tests/test119.ast
+++ b/asteroid/test-suites/regression-tests/test119.ast
@@ -13,7 +13,7 @@ let THREE_POINTS = pattern with ( *POINT_ONE , *POINT_TWO , *POINT_THREE ).
 function foo
     with x:%pattern do
         io @println("is a pattern").
-    with _ do
+    with x if not(x is %pattern) do
         io @println("not a pattern").
         end
 
@@ -23,4 +23,4 @@ foo(THREE_POINTS).
 -- Should not match as a pattern
 foo("Asteroid").
 foo(123).
-foo((1,2,3)).
\ No newline at end of file
+foo((1,2,3)).
diff --git a/asteroid/test-suites/regression-tests/test130.ast b/asteroid/test-suites/regression-tests/test130.ast
new file mode 100644
index 00000000..7ace9a41
--- /dev/null
+++ b/asteroid/test-suites/regression-tests/test130.ast
@@ -0,0 +1,8 @@
+-- patterns are just values: we can pattern match and index
+let z = pattern ((p,q),(r,t)).
+let (x,_) = z.
+let y = z@0.
+
+assert((1,2) is %[*x]%).
+assert((1,2) is %[*y]%).
+
diff --git a/asteroid/test-suites/regression-tests/test131.ast b/asteroid/test-suites/regression-tests/test131.ast
new file mode 100644
index 00000000..1eec448e
--- /dev/null
+++ b/asteroid/test-suites/regression-tests/test131.ast
@@ -0,0 +1,4 @@
+-- patterns can always match themselves.
+let z = pattern (p,q).
+assert(z is %[*z]%).
+
diff --git a/asteroid/test-suites/regression-tests/test132.ast b/asteroid/test-suites/regression-tests/test132.ast
new file mode 100644
index 00000000..ee49eedf
--- /dev/null
+++ b/asteroid/test-suites/regression-tests/test132.ast
@@ -0,0 +1,17 @@
+structure A with
+  data a.
+  data b.
+end
+
+let zp = pattern A(p,q). -- pattern constructed purely structural
+let zo = A(pattern p, pattern q). -- pattern constructed as an object
+
+-- both patterns can match objects
+assert(A(1,2) is %[*zp]%).
+assert(A(1,2) is %[*zo]%).
+
+-- two patterns are equivalent if they can match each other, 
+-- but these patterns are not equivalent: they cannot match each other
+assert(zo is %[*zp]%).
+assert(not(zp is %[*zo]%)).
+
diff --git a/asteroid/test-suites/run-tests.py b/asteroid/test-suites/run-tests.py
index 37751e6a..ea856185 100755
--- a/asteroid/test-suites/run-tests.py
+++ b/asteroid/test-suites/run-tests.py
@@ -18,6 +18,9 @@
 # give you details and a stack dump.
 verbose_failure = False
 
+# control whether to do redundancy checks
+redundancy = True
+
 # if your test case needs input from stdin please provide
 # a file named,
 #
@@ -56,5 +59,5 @@
             print("**********"+d+"/"+testname+"************")
             print(p)
             print("**********output***********")
-            interp(p,exceptions=verbose_failure)
+            interp(p,exceptions=verbose_failure,redundancy=redundancy)
             f.close()