Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- The latest upstream version of this can be found at:
--   http://angg.twu.net/dednat5/gab-tests.lua
--   http://angg.twu.net/dednat5/gab-tests.lua.html
--                    (find-dn5 "gab-tests.lua")
--
-- This file tests the functions defined in:
--   http://angg.twu.net/dednat5/gab.lua
--   http://angg.twu.net/dednat5/gab.lua.html
--                    (find-dn5 "gab.lua")
--
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2012apr25
-- License: GPL3

-- «.intro»		(to "intro")
-- «.infix-algorithm»	(to "infix-algorithm")
-- «.infix-1»		(to "infix-1")
-- «.rect-0»		(to "rect-0")
-- «.rect-1»		(to "rect-1")
-- «.prints»		(to "prints")
-- «.internal-vs-infix»	(to "internal-vs-infix")
-- «.eval-basic»	(to "eval-basic")
-- «.eval-basic-2»	(to "eval-basic-2")
-- «.infix-pyramids»	(to "infix-pyramids")
-- «.context-0»		(to "context-0")
-- «.context-1»		(to "context-1")
-- «.app-lambda-1»	(to "app-lambda-1")
-- «.app-lambda-def-1»	(to "app-lambda-def-1")
-- «.comprehension-1»	(to "comprehension-1")
-- «.grids-1»		(to "grids-1")
-- «.parse-1»		(to "parse-1")
-- «.parse-2»		(to "parse-2")
-- «.parse-3»		(to "parse-3")
-- «.modal»		(to "modal")
-- «.parse-lpeg»	(to "parse-lpeg")


-- «intro»  (to ".intro")
-- Consider a quantified expression, like this one (and note that to
-- keep everything in ascii we write "Fa" for "for all" and "Ex" for
-- "exists"):
--
--   Fa x in {2, 3, 4}. Ex y in {3, 4, 5}. 2*x <= y+3
--
-- using the constructors defined in this library we can create a
-- tree-ish repreresentation of that expression in memory with:
--
--   x = Var "x"
--   y = Var "y"
--   _2, _3, _4, _5 = Num(2), Num(3), Num(4), Num(5)
--   comparison    = Le(_2*x, y+_3)
--   ex_expression = Ex(y, Set(_3, _4, _5), comparison)
--   fa_expression = Fa(x, Set(_2, _3, _4), ex_expression)
--
-- All the subexpressions of "fa_expression", i.e., the ones marked
-- below (even numbers!),
--
--   Fa x in {2, 3, 4}. Ex y in {3, 4, 5}. 2*x <= y+3
--      -     -  -  -      -     -  -  -   - -    - -
--           \-------/          \-------/  \-/    \-/
--                                         \--------/
--                      \---------------------------/
--   \----------------------------------------------/
--
-- are represented internally as objects of the class "Expr", and so
-- they know how to respond to all the methods for Expr objects - most
-- importantly, they have a special "__tostring" that prints them in
-- infix notation using only the parentheses that are essential, and
-- they have an "eval". Here is a quick test:


--[[
-- «infix-algorithm»  (to ".infix-algorithm")
--
-- The algorith for displaying infix expressions
-- =============================================
-- The code for displaying expressions in infix notation was inspired
-- by something that I learned in the code for Andrej Bauer's PLZoo:
--
--    (find-es "ml" "plzoo")
--    (find-es "ml" "levy")
--    (find-levyfile "syntax.ml" "string_of_expr")
--    http://andrej.com/plzoo/
--    http://andrej.com/plzoo/html/miniml.html
--      ^ look for "string_of_expr"
--
-- The basic idea is that each fully parenthesised expression like
--
--   22 + (33 * ((44 - 55) - (66 - 77)))
--
-- has a unique representation with minimal parenthesisation, which in
-- the case of the expression above is:
--
--   22 +  33 *  (44 - 55  - (66 - 77))
--
-- to discover where those essential parentheses are, let's mark them
-- in the edges of the representation of the expression as a tree:
--
--          +
--        /   \
--     22       *
--            /   \()
--         33       -
--                /   \()
--              -       -
--            /   \   /   \
--         44     55 66     77
--
-- If we write certain numbers at the top and the bottom of each
-- connective, the rule becomes evident. Each edge connects a bottom
-- number (above) to a top number (below). When b >= t, use
-- parentheses.
--                ___
--               / 7 \
--              /  +  \
--             |_6___7_|
--           /           \
--        22              ___   
--                       / 8 \  
--                      /  *  \ 
--                     |_7___8_|
--                   /           \()
--                33              ___                   
--                               / 7 \          
--                              /  -  \         
--                             |_6___7_|        
--                           /           \()      
--                        ___             ___   
--                       / 7 \           / 7 \  
--                      /  -  \         /  -  \ 
--                     |_6___7_|       |_6___7_|
--                   /           \   /           \
--                44            55  66             77
--]]


-- (find-angg ".emacs" "to-shadow")
-- (find-eapropos "shadow")

--[[
-- «infix-1»  (to ".infix-1")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
x = Var "x"
y = Var "y"
_2, _3, _4, _5 = Num(2), Num(3), Num(4), Num(5)
comparison    = Le(_2*x, y+_3)
ex_expression = Ex(y, Set(_3, _4, _5), comparison)
fa_expression = Fa(x, Set(_2, _3, _4), ex_expression)
ex_expression:print()   -->                    Ex y in {3, 4, 5}. 2*x <= y+3
fa_expression:print()   --> Fa x in {2, 3, 4}. Ex y in {3, 4, 5}. 2*x <= y+3
fa_expression:eval():print()  --> T

x:Whens(Set(_2, _3, _4), ex_expression)




--[[
-- «rect-0»  (to ".rect-0")
-- Low-level tests for Rect
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
r = Rect {w=3, "a", "ab", "abc"}
= r
= r..r
= r.."foo"
= "--"..r
= rectconcat("+", {2, 3})
= rectconcat("+", {2, 34, 5})
= r:under_("Fa")..r:under(".")
= r:under_("Fa")
= r:under(".")


-- High-level tests for Rect
-- «rect-1»  (to ".rect-1")
--[[
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
= (_2 * _3 + _4 * - _5):torect()
comparison    = Le(_2*x, y+_3)
ex_expression = Ex(y, Set(_3, _4, _5), comparison)
fa_expression = Fa(x, Set(_2, _3, _4), ex_expression)

=        fa_expression
= tolisp(fa_expression)
      PP(fa_expression)
=        fa_expression:torect()

= fa_expression

e = fa_expression
= "eval( "..e:torect().." ) --> "..e:eval():torect()

-- Output:
--   eval( Fa_.________.                      ) --> T
--         |  |        |                     
--         x  {}_.__.  Ex_.________.         
--            |  |  |  |  |        |         
--            2  3  4  y  {}_.__.  <=____.   
--                        |  |  |  |     |   
--                        3  4  5  *__.  +__.
--                                 |  |  |  |
--                                 2  x  y  3





--[[
-- «prints»  (to ".prints")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- Some ways of printing an expression and its result
A = Set(_2, _3, _5)
B = Set(_2, _3)
expr = Le(a*a, Num(10))
a:Whens(A, expr)
a:Whens(B, expr)
Fa(a, A, expr):peval()
Fa(a, B, expr):peval()

= _2 * _3 + _4 * _5
 (_2 * _3 + _4 * _5):peval()
= (_2 * _3):Dbg() + (_4 * _5):Dbg()
 ((_2 * _3):Dbg() + (_4 * _5):Dbg()):peval()


--[[
-- «internal-vs-infix»  (to ".internal-vs-infix")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- The internal representation vs. the infix representation
PP(2)
PP(_2, otype(_2))
=  _2 + _3
PP(_2 + _3)
  (_2 + _3):lprint()


--[[
-- «eval-basic»  (to ".eval-basic")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- Basic evaluation
=   _2 +   _3
=  (_2 +   _3):eval()
=  (_2 + - _3):eval()
PP((_2 + - _3):eval())
= Le(_2, _3)
= Le(_2, _3):eval()
= Ge(_2, _3):eval()


--[[
-- «eval-basic-2»  (to ".eval-basic-2")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
=  Ge(a+(b*(c-d)), a)
=  Ge(a, a+(b*(c-d)))
PP(Ge(a, a+(b*(c-d))))
  (Ge(a, a+(b*(c-d)))):lprint()
= Set(a*a, b, c, Tuple(a, b))
 (Set(a*a, b, c, Tuple(a, b))):lprint()
= Fa(a, Set(b, c), Le(a, d))
 (Fa(a, Set(b, c), Le(a, d))):lprint()


e   = Le(_2*a, b+_3)
ee  = Ex(b, Set(_3, _4, _5), e)
eee = Fa(a, Set(_2, _3, _4), ee)
= And(ee, ee)
= And(e, eee)

= _2:eval()
= _2 + _3
= (_2 + _3):eval()
= (_2 * - _3):eval()
PP(_2)
PP(- _3)
PP(   _3 :neval())
PP((- _3):neval())



--[[
-- «infix-pyramids»  (to ".infix-pyramids")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- Tests for the parenthesisation algorithm (using "pyramids")
= And(And(a, b), And(c, d))
= Or (Or (a, b), Or (c, d))
= Imp(Imp(a, b), Imp(c, d))
pyr  = function (F) print(F(F(a, b), F(c, d))) end
pyr2 = function (F, G) print(F(G(a, b), G(c, d)), G(F(a, b), F(c, d))) end
pyrs = function (T)
    for i=1,#T-1 do pyr(T[i]); pyr2(T[i], T[i+1]) end
    pyr(T[#T])
  end
pyr(And)
pyr(Or)
pyr(Imp)
pyr2(And, Or)
pyr2(And, Not)
pyrs {
  Unm, Mul, Div, Add, Sub,
  Eq, Lt, Le, Ge, Gt,
  Not, And, Or, Imp,
}


--[[
-- «context-0»  (to ".context-0")
-- This is obsolete, see:
-- (find-dn5 "gab.lua")
-- (find-dn5 "gab.lua" "contexts-test")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- Printing the context
comparison    = Le(_2*x, y+_3)
comparison    = Le(_2*x, y+_3):Dbg()
ex_expression = Ex(y, Set(_3, _4, _5), comparison)
ex_expression = Ex(y, Set(_3, _4, _5), comparison):Dbg()
fa_expression = Fa(x, Set(_2, _3, _4), ex_expression)
fa_expression:peval()

-- [x=2 y=3]                             2*x <= y+3  -->  T
-- [x=2 y=4]                             2*x <= y+3  -->  T
-- [x=2 y=5]                             2*x <= y+3  -->  T
-- [x=2]              Ex y in {3, 4, 5}. 2*x <= y+3  -->  T
-- [x=3 y=3]                             2*x <= y+3  -->  T
-- [x=3 y=4]                             2*x <= y+3  -->  T
-- [x=3 y=5]                             2*x <= y+3  -->  T
-- [x=3]              Ex y in {3, 4, 5}. 2*x <= y+3  -->  T
-- [x=4 y=3]                             2*x <= y+3  -->  F
-- [x=4 y=4]                             2*x <= y+3  -->  F
-- [x=4 y=5]                             2*x <= y+3  -->  T
-- [x=4]              Ex y in {3, 4, 5}. 2*x <= y+3  -->  T
-- Fa x in {2, 3, 4}. Ex y in {3, 4, 5}. 2*x <= y+3  -->  T



--[[
-- «context-1»  (to ".context-1")
-- Basic tests for contexts
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
-- dofile "gab.lua"
c = newcontext {x=22, y=33}
c:print()
c:push("z", 44):print()
c:push("x", 99):print()
c:push("y", nil):print()
PP(c)
c:pop():print()
c:pop():print()
c:pop():print()
c:pop():print()   -- error



--[[
-- «app-lambda-1»  (to ".app-lambda-1")
-- Basic tests for lambda and app
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
f = Lambda(x, x + _2)
f7 = App(f, _3 + _4)
f:print()
f:peval()
f7:print()
f7:lprint()
f7:rprint()
f7:peval()

-- «app-lambda-def-1»  (to ".app-lambda-def-1")
P = Def "P"
defs.P = Lambda(x, Le(x, _2))
App(P, _1):peval()
App(P, _2):peval()
App(P, _3):peval()



-- «comprehension-1»  (to ".comprehension-1")
-- (find-dn5 "gab.lua" "comprehension")
--[[
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
_10 = Num(10)
A = Set(_1, _2, _3)
B = Setof(Gen(x, A), Gen(y, A), Filt(Le(x, y)), Collect(_10*x+y))
C = Setof(Gen(x, A), Gen(y, A), Filt(Le(x, y)), Collect(Tuple(x, y)))
D = Subset(Gen(x, A), Filt(Neq(x, _2)), Collect(x))
    Setof(Gen(x, A), Collect(Tuple(x, x*x))):preval()
B:preval()
C:preval()
D:preval()



--[[
-- «grids-1»  (to ".grids-1")
-- Test the code for drawing tables
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
defs:vprint()
print(columns())

Cols = {
  App(P,  k),
  P1, P2, P3, P4,
  False,
  Def("E_4"), Def("E'_3"), Def("E_3"), Def("E_1"), Def("E'_2"), Def("E_2"),
  True,
}
Ps = {
   False,
   Ge(k, _4),
   Or(Eq(k, _1), Eq(k, _4)),
   Ge(k, _3),
   Or(Eq(k, _2), Eq(k, _3)),
   Ge(k, _2),
   True,
}
defs:vprint()
= columns()



-- «parse-1»  (to ".parse-1")
-- «parse-2»  (to ".parse-2")
-- (find-dn5file "gab.lua" "Expr.__index.infix =")
-- (find-dn5 "gab.lua" "Context")
-- (find-dn5 "gab.lua" "precedence")



--[[
-- «parse-3»  (to ".parse-3")
-- (find-dn5 "gab.lua" "precedence-table")
-- Parsing expressions (very preliminary)
-- (find-es "lua5" "lpeg-quickref")
-- (find-dn5 "gab.lua" "recursive-descent")
-- (find-dn5 "gab.lua" "recursive-descent" "pa_expr =")

* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
pparsee "2 * 3 + 4 * 5"
pparsee "Fa x in { 2 , 3 , 4 } . x * x < 10"
pparsee "Ex x in { 2 , 3 , 4 } . x * x < 10"
pparsee "Fa x in { } . x * x < 10"
pparsee "Ex x in { } . x * x < 10"

pparsee "{ 10 * x + y | x <- { 2 , 3 } , y <- { 3 , 4 } }"
pparsee "{ 10 * x + y | x <- { 2 , 3 } , y <- { 3 , 4 } , x < y }"
pparsee "{  ( x , y ) | x <- { 2 , 3 } , y <- { 3 , 4 } , x < y }"
pparsee "  \\ x . x + 2        "
pparsee "( \\ x . x + 2 )   3  "    -- here the "3" is not parsed
pparsee "( \\ x . x + 2 ) ( 3 )"

pparsee "( )"

pparsee "2 * 3"

pparse  "2 + 3 * 4 + 5 * 6 * 7 (eof)"
pparse  "2 * ( 3 * 4 + 5 * 6 ) + 7"

pparse  "2 in { 2 , 3 , 4 }"
pparse  "2 in { 2 | 3 , 4 }"
pparse  "2 in { 10 * x + y | x <- A , y <- B }"
pparsee "{ 10 * x + y | x <- { 2 , 3 } , y <- { 3 , 4 } }"
pparsee "{ 10 * x + y | x <- { 2 , 3 } , y <- { 3 , 4 } , x < y }"
pparse  "x <= 4"
pparse  "2 in { x <- A | x <= 4 }"
pparse  "{ x , y }"





--[[
-- «modal»  (to ".modal")
-- (find-dn5 "gab.lua" "modal")
-- (find-dn5file "gab.lua" "rectconcat =")
-- (find-dn5file "gab.lua" "op == \"Mo\"")
* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
sr = stringtorect
pp = function (f1, s1, f2, s2)
    PP(f1(s1))
    PP(f2(s2))
    print(f1(s1)..f2(s2)..","..f1(s1)..","..f2(s2))
  end
pp(sr, "abc\ndef", sr, " &")
pp(sr, "abc"     , sr, " &")

PP(sr"abc\ndef")
PP(sr"abc\nde")
PP(sr"abc\nde" .. sr" &")
PP(sr"abc\nde" .. sr" &\nfg")
PP(sr"abc\nde" .. sr"abc\nde")
PP(splitlines " &\nfg")


a = Vee_ "123"
b = Vee  "123"
= b
= And(b, b)
= And(b, b):tolisp()
= And(b, b):torect()
= And(_2, _3)
= b .. "!"
=  b:infix()
PP(b:infix())
= b:tolisp()
print(otype(b:infix()))
print(otype(b))
= b
= b[1].."abc"
= b[1].." bc"
= b[1].." & "
= b[1]..torect(" & ")
= b[1].."&"



--[[
-- «parse-lpeg»  (to ".parse-lpeg")
-- Suffixes on patterns:
--   Pat_c    is a pattern with exactly one capture
--   Pat_scp  is OptSpaces * Pat_c * lpeg.Cp()

* (eepitch-gab)
* (eepitch-kill)
* (eepitch-gab)
--]]
etest "2 <= 3 + 4*5*6 & 7 < 8"
eteste "Fa a<-{2,3,4}. Ex b<-{2,3,4}. a*b>10"
eteste "Ex a<-{2,3,4}. Ex b<-{2,3,4}. a*b>10"

eteste "2*3+4*5"

etest "{1,2}"
etest "{1}"
etest "{}"
etest "{1|2}"
etest "{1|2,3}"
etest "{1<-2|3,4}"

eteste "    {2, 3, 4}        "
eteste "{a<-{2, 3, 4} | a<=3}"
eteste "Fa a<-{2,3,4}. Ex b<-{2,3,4}. a*b>10"
eteste "Ex a<-{2,3,4}. Ex b<-{2,3,4}. a*b>10"
eteste "Ex a<-{2,3,4}. Ex b<-{2,3,4}. a*b>10"
eteste "\\ a. 2+a*a"
eteste "(\\ a. a*a)(5)"

etest "2 <= 3 + 4*5*6 & 7 < 8"


eteste "2*3+4*5"
eteste "Fa x<-{2,3,4}. x*x<10"
eteste "Ex x<-{2,3,4}. x*x<10"
eteste "Fa x<-{}.x*x<10"
eteste "Ex x<-{}.x*x<10"

eteste "{10*x+y | x<-{2,3}, y<-{3,4}}"
eteste "{10*x+y |x <-{2,3} ,y<-{3,4} ,x<y}"
eteste "{(x,y) | x<-{2,3} ,y<-{3,4}, x<y}"
eteste "\\x.x+2"
eteste "(\\x.x+2)3"   -- here the "3" is not parsed
eteste "(\\x.x+2)(3)"

eteste "()"

eteste "2*3"

etest  "2+3*4+5*6*7 (eof)"
etest  "2*(3*4+5*6)+7"

etest  "2<-{2,3,4}"
etest  "2<-{2|3,4}"
etest  "2 in {10*x+y | x<-A ,y<-B}"
eteste "{10*x+y | x<-{2,3}, y<-{3,4}}"
eteste "{10*x+y | x<-{2,3} ,y<-{3,4} , x<y}"
eteste "{(x,y) | x<-{2,3} ,y<-{3,4} , x<y}"
etest  "x<=4"






-- Local Variables:
-- coding:             raw-text-unix
-- ee-anchor-format:   "«%s»"
-- End: