|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://angg.twu.net/LUA/ZHA1.lua.html
-- http://angg.twu.net/LUA/ZHA1.lua
-- (find-angg "LUA/ZHA1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- This is a rewritten version of
-- (find-dn6file "zhas.lua")
-- that uses Pict2e1.lua to generate LaTeX code.
-- (defun a () (interactive) (find-angg "LUA/Pict2e1.lua"))
-- (defun b () (interactive) (find-angg "LUA/ZHA1.lua"))
-- (defun z () (interactive) (find-dn6 "zhas.lua"))
-- (defun ab () (interactive) (find-2b '(a) '(b)))
-- (defun bz () (interactive) (find-2b '(b) '(z)))
-- (defun et () (interactive) (find-angg "LATEX/2022pict2e.tex"))
-- (defun eb () (interactive) (find-angg "LATEX/2022pict2e-body.tex"))
-- (defun ao () (interactive) (find-angg "LATEX/2022pict2e.lua"))
-- (defun v () (interactive) (find-pdftools-page "~/LATEX/2022pict2e.pdf"))
-- (defun tb () (interactive) (find-ebuffer (eepitch-target-buffer)))
-- (defun etv () (interactive) (find-wset "13o2_o_o" '(tb) '(v)))
-- (setenv "PICT2ELUADIR" "~/LATEX/")
-- «.V» (to "V")
-- «.V-tests» (to "V-tests")
-- «.BoundingBox» (to "BoundingBox")
-- «.BoundingBox-tests» (to "BoundingBox-tests")
-- «.AsciiPicture» (to "AsciiPicture")
-- «.AsciiPicture-tests» (to "AsciiPicture-tests")
-- «.TArrow» (to "TArrow")
-- «.TArrow-tests» (to "TArrow-tests")
-- «.Squig» (to "Squig")
-- «.Squig-tests» (to "Squig-tests")
-- «.ZHA» (to "ZHA")
-- «.ZHA-connectives» (to "ZHA-connectives")
-- «.ZHA-getcuts» (to "ZHA-getcuts")
-- «.ZHA-walls» (to "ZHA-walls")
-- «.ZHA-shrinktop» (to "ZHA-shrinktop")
-- «.ZHA-tests» (to "ZHA-tests")
-- «.ZHA-tests-walls» (to "ZHA-tests-walls")
-- «.ZHA-test-connectives» (to "ZHA-test-connectives")
-- «.ZHA-test-generators» (to "ZHA-test-generators")
-- «.ZHA-test-shrinktop» (to "ZHA-test-shrinktop")
-- «.shortoperators» (to "shortoperators")
-- «.shortoperators-tests» (to "shortoperators-tests")
-- «.LR» (to "LR")
-- «.LR-tests» (to "LR-tests")
-- «.LR-putxy-tests» (to "LR-putxy-tests")
-- «.LR-twocolgraph-tests» (to "LR-twocolgraph-tests")
-- «.LR-fromtcgspec-tests» (to "LR-fromtcgspec-tests")
-- «.LR-shrinktop-tests» (to "LR-shrinktop-tests")
require "Pict2e1" -- (find-angg "LUA/Pict2e1.lua")
checkrange = function(a, b, c, err)
if a <= b and b <= c then return true end
if err then error(format("%s", err, a, b, c)) end
end
isint = function (x) return math.floor(x) == x end
ishalf = function (x) return isint(x + 0.5) end
pad = function (spaces, str)
return ((str or "")..spaces):sub(1, #spaces)
end
-- ____ ____ _
-- |___ \| _ \ __ _____ ___| |_ ___ _ __ ___
-- __) | | | | \ \ / / _ \/ __| __/ _ \| '__/ __|
-- / __/| |_| | \ V / __/ (__| || (_) | | \__ \
-- |_____|____/ \_/ \___|\___|\__\___/|_| |___/
--
-- This class supports the usual operations on 2D vectors and also
-- some of the logical operations on elements of a ZHA - even the
-- implication,
-- IIRC...
-- Adapted from: (find-dn6 "picture.lua" "V")
-- «V» (to ".V")
V = Class {
type = "V",
__tostring = function (v) return pformat("(%s,%s)", v[1], v[2]) end,
__add = function (v, w) return V{v[1]+w[1], v[2]+w[2]} end,
__sub = function (v, w) return V{v[1]-w[1], v[2]-w[2]} end,
__unm = function (v) return v*-1 end,
__mul = function (v, w)
local ktimesv = function (k, v) return V{k*v[1], k*v[2]} end
local innerprod = function (v, w) return v[1]*w[1] + v[2]*w[2] end
if type(v) == "number" and type(w) == "table" then return ktimesv(v, w)
elseif type(v) == "table" and type(w) == "number" then return ktimesv(w, v)
elseif type(v) == "table" and type(w) == "table" then return innerprod(v, w)
else error("Can't multiply "..tostring(v).."*"..tostring(w))
end
end,
--
fromxy = function (x, y) return V{x, y} end,
fromlr = function (l, r) return V{l, r}:lrtoxy() end,
fromlrdir = function (l, r, ensw) return V.fromlr(l, r):walk(ensw) end,
fromab = function (a, b)
local ton = tonumber
if type(a) == "table" then return a
elseif type(a) == "number" then return V.fromxy(a, b)
elseif type(a) == "string" then
local x, y = a:match("^%((.-),(.-)%)$")
if x then return V.fromxy(ton(x), ton(y)) end
local l, r = a:match("^(%d)(%d)$")
if l then return V.fromlr(ton(l), ton(r)) end
local l, r, ensw = a:match("^(%d)(%d)([ensw])$")
if l then return V.fromlrdir(ton(l), ton(r), ensw) end
error("V.fromab() received a bad string: "..a)
end
end,
__index = {
xytolr = function (v)
local x, y = v[1], v[2]
local l = toint((y - x) / 2)
local r = toint((y + x) / 2)
return V{l, r}
end,
lrtoxy = function (v)
local l, r = v[1], v[2]
local x = r - l
local y = r + l
return V{x, y}
end,
--
todd = function (v) return v[1]..v[2] end,
to12 = function (v) return v[1], v[2] end,
to_x_y = function (v) return v:to12() end,
to_l_r = function (v) return v:xytolr():to12() end,
xy = function (v) return "("..v[1]..","..v[2]..")" end,
lr = function (v) local l, r = v:to_l_r(); return l..r end,
--
naiveprod = function (v, w)
return V{v[1]*w[1], v[2]*w[2]}
end,
naivemin = function (v, w)
return V{min(v[1], w[1]), min(v[2], w[2])}
end,
naivemax = function (v, w)
return V{max(v[1], w[1]), max(v[2], w[2])}
end,
--
-- For V.fromlrdir() and from zha.ne / zha.nw
s = function (v) return v+V{ 0, -1} end,
n = function (v) return v+V{ 0, 1} end,
w = function (v) return v+V{-1, 0} end,
e = function (v) return v+V{ 1, 0} end,
se = function (v) return v+V{ 1, -1} end,
sw = function (v) return v+V{-1, -1} end,
ne = function (v) return v+V{ 1, 1} end,
nw = function (v) return v+V{-1, 1} end,
walk = function (v, ensw) return v[ensw](v) end,
--
-- For: (ph1p 11 "prop-calc-ZHA")
-- (ph1a "prop-calc-ZHA")
And = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return V{min(Pl, Ql), min(Pr, Qr)}:lrtoxy()
end,
Or = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return V{max(Pl, Ql), max(Pr, Qr)}:lrtoxy()
end,
above = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return Pl >= Ql and Pr >= Qr
end,
below = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return Pl <= Ql and Pr <= Qr
end,
leftof = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return Pl >= Ql and Pr <= Qr
end,
rightof = function (P, Q)
local Pl, Pr = P:to_l_r()
local Ql, Qr = Q:to_l_r()
return Pl <= Ql and Pr >= Qr
end,
},
}
v = V.fromab
lr = function (l, r) return V.fromlr(l, r) end
-- «V-tests» (to ".V-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "ZHA1.lua"
= V{3,4} --> (3,4)
= V{3,4} - V{2,1} --> (1,3)
= V{3,4} + V{2,1} --> (5,5)
= V{3,4} * V{2,1} --> 10
= V{3,4} * -10 --> (-30,-40)
= -10 * V{3,4} --> (-30,-40)
= V{-3,3}:xytolr() --> (3,0)
= V{3,3}:xytolr() --> (0,3)
= V{2,4}:xytolr() --> (1,3)
= v(-3,3) --> (-3,3)
= v(-3,3):to12() --> -3 3
= v(-3,3):lr() --> 30
= v"30" --> (-3,3)
= v"30":lr() --> 30
= v"20" --> (-2,2)
= v"02" --> (2,2)
= v"22" --> (0,4)
--]]
-- ____ _ _ ____
-- | __ ) ___ _ _ _ __ __| (_)_ __ __ _| __ ) _____ __
-- | _ \ / _ \| | | | '_ \ / _` | | '_ \ / _` | _ \ / _ \ \/ /
-- | |_) | (_) | |_| | | | | (_| | | | | | (_| | |_) | (_) > <
-- |____/ \___/ \__,_|_| |_|\__,_|_|_| |_|\__, |____/ \___/_/\_\
-- |___/
-- A BoundingBox object contains:
-- a field "x0x0" with a V object (the lower left corner),
-- a field "x1x1" with a V object (the upper right corner).
--
-- «BoundingBox» (to ".BoundingBox")
BoundingBox = Class {
type = "BoundingBox",
new = function () return BoundingBox {} end,
__tostring = function (bb) return bb:tostring() end,
__index = {
nonempty = function (bb) return bb.x0y0 end,
empty = function (bb) return not bb.x0y0 end,
tostring = function (bb, h)
if bb:empty() then return "BoundingBox: empty" end
if h then
return pformat("BoundingBox: (x0,y0)=%s (x1,y1)=%s", bb.x0y0, bb.x1y1)
end
return pformat("BoundingBox: \n (x1,y1)=%s\n (x0,y0)=%s", bb.x1y1, bb.x0y0)
end,
--
addpoint = function (bb, v)
if bb.x0y0 then bb.x0y0 = bb.x0y0:naivemin(v) else bb.x0y0 = v end
if bb.x1y1 then bb.x1y1 = bb.x1y1:naivemax(v) else bb.x1y1 = v end
return bb
end,
addbox = function (bb, v, delta0, delta1)
bb:addpoint(v+delta0)
return bb:addpoint(v+(delta1 or -delta0))
end,
x0y0x1y1 = function (bb)
local x0, y0 = bb.x0y0:to_x_y()
local x1, y1 = bb.x1y1:to_x_y()
return x0, y0, x1, y1
end,
x0x1y0y1 = function (bb)
local x0, y0 = bb.x0y0:to_x_y()
local x1, y1 = bb.x1y1:to_x_y()
return x0, x1, y0, y1
end,
--
merge = function (bb1, bb2)
if bb2.x0y0 then bb1:addpoint(bb2.x0y0) end
if bb2.x1y1 then bb1:addpoint(bb2.x1y1) end
return bb1
end,
},
}
-- «BoundingBox-tests» (to ".BoundingBox-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "ZHA1.lua"
bb = BoundingBox.new()
PP(bb)
= bb
= bb:addpoint(v(2, 4))
PP(bb)
= bb:addbox(v(6, 7), v(.5, .5))
= bb:addbox(v(1, 2), v(.5, .5))
= bb:x0x1y0y1()
= bb
= bb:tostring()
= bb:tostring("h")
PP(bb)
--]]
-- _ _ _ ____ _ _
-- / \ ___ ___(_|_) _ \(_) ___| |_ _ _ _ __ ___
-- / _ \ / __|/ __| | | |_) | |/ __| __| | | | '__/ _ \
-- / ___ \\__ \ (__| | | __/| | (__| |_| |_| | | | __/
-- /_/ \_\___/\___|_|_|_| |_|\___|\__|\__,_|_| \___|
--
-- «AsciiPicture» (to ".AsciiPicture")
AsciiPicture = Class {
type = "AsciiPicture",
new = function (padstr)
return AsciiPicture {
padstr = padstr or " ",
intbbox = BoundingBox.new(),
halfbbox = BoundingBox.new(),
grid = VTable {},
}
end,
__tostring = function (ap) return ap:tostring() end,
__index = {
get = function (ap, x, y) return ap.grid[y] and ap.grid[y][x] end,
pget = function (ap, x, y)
local contents = ap:get(x, y)
local padstr = isint(x) and ap.padstr or " "
return pad(padstr, contents or "")
end,
put = function (ap, x, y, str)
if isint(x) and isint(y) then ap.intbbox :addpoint(v(x, y))
elseif ishalf(x) and ishalf(y) then ap.halfbbox:addpoint(v(x, y))
else error(pformat("Not intint and not halfhalf %s %s", x, y))
end
ap.grid[y] = ap.grid[y] or HTable {}
ap.grid[y][x] = str
return ap
end,
putv = function (ap, v, str) ap:put(v[1], v[2], str) end,
putlr = function (ap, v, str) ap:put(v[1], v[2], str or v:lr()) end,
--
linestr = function (ap, xs, y)
local f = function (x) return ap:pget(x, y) end
return mapconcat(f, xs, "")
end,
gridstr = function (ap, xs, ys)
local g = function (y) return ap:linestr(xs, y) end
return mapconcat(g, ys, "\n")
end,
ix0 = function (ap) return ap.intbbox.x0y0[1] end,
iy0 = function (ap) return ap.intbbox.x0y0[2] end,
ix1 = function (ap) return ap.intbbox.x1y1[1] end,
iy1 = function (ap) return ap.intbbox.x1y1[2] end,
hx0 = function (ap) return ap.halfbbox.x0y0[1] end,
hy0 = function (ap) return ap.halfbbox.x0y0[2] end,
hx1 = function (ap) return ap.halfbbox.x1y1[1] end,
hy1 = function (ap) return ap.halfbbox.x1y1[2] end,
bx0 = function (ap) return min(ap:ix0(), ap:hx0()) end,
by0 = function (ap) return min(ap:iy0(), ap:hy0()) end,
bx1 = function (ap) return max(ap:ix1(), ap:hx1()) end,
by1 = function (ap) return max(ap:iy1(), ap:hy1()) end,
ixs = function (ap) return seq(ap:ix0(), ap:ix1(), 1) end,
iys = function (ap) return seq(ap:iy1(), ap:iy0(), -1) end,
hxs = function (ap) return seq(ap:hx0(), ap:hx1(), 1) end,
hys = function (ap) return seq(ap:hy1(), ap:hy0(), -1) end,
bxs = function (ap) return seq(ap:bx0(), ap:bx1(), 0.5) end,
bys = function (ap) return seq(ap:by1(), ap:by0(), -0.5) end,
igridstr = function (ap) return ap:gridstr(ap:ixs(), ap:iys()) end,
hgridstr = function (ap) return ap:gridstr(ap:hxs(), ap:hys()) end,
bgridstr = function (ap) return ap:gridstr(ap:bxs(), ap:bys()) end,
--
hasintpoints = function (ap) return ap.intbbox:nonempty() end,
hashalfpoints = function (ap) return ap.halfbbox:nonempty() end,
tostring = function (ap)
if ap:hasintpoints() then
if ap:hashalfpoints() then
return ap:bgridstr()
else
return ap:igridstr()
end
else
if ap:hashalfpoints() then
return ap:hgridstr()
else
return "(empty)"
end
end
end,
--
tostring0 = function (ap)
return pformat("intbbox: %s\nhalfbbox: %s\npadstr: \"%s\"",
ap.intbbox :tostring("h"),
ap.halfbbox:tostring("h"),
ap.padstr)
end,
--
setflags = function (ap, flags) ap.flags = flags; return ap end,
flag = function (ap, flag) return ap.flags:match(flag) end,
--
drawline = function (ap, v0, v1)
local Dx, Dy = v1[1]-v0[1], v1[2]-v0[2]
if Dx == 0 and Dy == 0 then return end
local char
if Dx == Dy then char = "/" end
if Dx == -Dy then char = "\\" end
if not char then error("Bad slope") end
local Sx, Sy = (Dx > 0 and 1 or -1), (Dy > 0 and 1 or -1)
local vunit = v(Sx, Sy)
local n = Dx / Sx
for t=0.5,n-0.5 do ap:putv(v0 + t*vunit, char) end
return ap
end,
drawlines = function (ap, points, poly)
if type(points) == "string" then points = split(points) end
for i=1,#points-1 do ap:drawline(v(points[i]), v(points[i+1])) end
if poly then ap:drawline(v(points[#points]), v(points[1])) end
return ap
end,
},
}
-- «AsciiPicture-tests» (to ".AsciiPicture-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "ZHA1.lua"
ap = AsciiPicture.new()
= ap:tostring0()
= ap
ap:put(0, 0, "foo")
= ap
= ap:pget(0, 0)
= ap:pget(1, 1)
= ap
for l=0,3 do
for r=0,4 do
ap:putlr(lr(l, r))
end
end
= ap
ap:put(0.5, 0.5, "\\")
= ap
= v"10s"
ap:drawline(v"10s", v"14e")
= ap
= ap:hgridstr()
= ap:hgridstr()
= v(v(2,3))
= ap:drawlines("00s 30w 34n 04e", "poly")
--]==]
-- _____ _
-- |_ _|/ \ _ __ _ __ _____ __
-- | | / _ \ | '__| '__/ _ \ \ /\ / /
-- | |/ ___ \| | | | | (_) \ V V /
-- |_/_/ \_\_| |_| \___/ \_/\_/
--
-- This is a tarrow, or a tarrows: "46; 32, 15 26"
-- The "tarrow" above corresponds to the 2CG that has top elements 4_
-- and _6, and inter-column arrows 3_->_2, 1_<-_5 and 2_<-_6.
-- It corresponds to this squig: "123RRL43R21".
-- See: (ph1p 28 "2CGs")
-- (ph1a "2CGs")
-- (ph1p 33 "converting-ZHAs-2CAGs")
-- (ph1a "converting-ZHAs-2CAGs")
-- «TArrow» (to ".TArrow")
TArrow = Class {
type = "TArrow",
from0 = function (str)
local lr,LR,RL = str:match("^(.*);(.*),(.*)$")
lr = lr:gsub("[^0-9]", "")
local maxl = tonumber(lr:sub(1,1))
local maxr = tonumber(lr:sub(2,2))
local ap = AsciiPicture.new(" ")
return TArrow { maxl=maxl, maxr=maxr, LR=LR, RL=RL, ap=ap }
end,
from = function (str)
return TArrow.from0(str):drawrect():erasearrows()
end,
--
__tostring = function (ta) return ta.ap:tostring() end,
__index = {
maxy = function (ta) return ta.maxl + ta.maxr end,
minx = function (ta) return -ta.maxl end,
maxx = function (ta) return ta.maxr end,
--
drawrect = function (ta)
for l=0,ta.maxl do
for r=0,ta.maxr do
ta.ap:putlr(lr(l, r))
end
end
return ta
end,
eraserect = function (ta, l0,r0, l1,r1)
for l=min(l0,l1),max(l0,l1) do
for r=min(r0,r1),max(r0,r1) do
ta.ap:putv(lr(l, r), nil)
end
end
return ta
end,
eraselrarrow = function (ta, l,r)
ta:eraserect(ta.maxl,0, l,r-1)
return ta
end,
eraserlarrow = function (ta, l,r)
ta:eraserect(0,ta.maxr, l-1,r)
return ta
end,
erasearrows = function (ta)
local lr_to_l_r = function (lr)
return tonumber(lr:sub(1,1)), tonumber(lr:sub(2,2))
end
for _,lr in ipairs(split(ta.LR)) do ta:eraselrarrow(lr_to_l_r(lr)) end
for _,lr in ipairs(split(ta.RL)) do ta:eraserlarrow(lr_to_l_r(lr)) end
return ta
end,
--
newtop = function (ta, l, r)
ta:eraserect(l+1, 0, ta.maxl, ta.maxr)
ta:eraserect(0, r+1, ta.maxl, ta.maxr)
ta.maxl = l
ta.maxr = r
return ta
end,
--
validxy = function (ta, x, y)
return ta.ap:get(x, y)
end,
calcminx = function (ta, y)
for x=ta:minx(),ta:maxx() do if ta:validxy(x, y) then return x end end
end,
calcmaxx = function (ta, y)
for x=ta:maxx(),ta:minx(),-1 do if ta:validxy(x, y) then return x end end
end,
validxs = function (ta, y)
return ta:calcminx(y), ta:calcmaxx(y)
end,
--
digit = function (ta, y)
local a,b = ta:validxs(y)
local c,d = ta:validxs(y - 1)
if b-a == d-c - 2 then return (b-a)/2+1 end
if b-a == d-c + 2 then return (b-a)/2+1 end
if b-a == d-c and a == c-1 then return "L" end
if b-a == d-c and a == c+1 then return "R" end
error("Bad digit")
end,
getsquig = function (ta)
local sqg = "1"
for y=1,ta:maxy() do sqg = sqg..ta:digit(y) end
return sqg
end,
--
gettarrows = function (ta)
local tolr = function (x, y) return " "..v(x,y):lr() end
local lrs, rls = "", ""
for y = 2,ta:maxy() do
local a,b = ta:validxs(y)
local c,d = ta:validxs(y - 1)
local e,f = ta:validxs(y - 2)
if a == c-1 and c == e+1 then lrs = lrs..tolr(a, y) end
if b == d+1 and d == f-1 then rls = rls..tolr(b, y) end
end
return ta.maxl..ta.maxr..";"..lrs..","..rls
end,
--
validlr = function (ta, l, r)
return ta.ap:get(lr(l, r):to_x_y())
end,
calcminl = function (ta, r)
for l=0,ta.maxl do if ta:validlr(l, r) then return l end end
end,
calcminr = function (ta, l)
for r=0,ta.maxr do if ta:validlr(l, r) then return r end end
end,
calcmaxl = function (ta, r)
for l=ta.maxl,0,-1 do if ta:validlr(l, r) then return l end end
end,
calcmaxr = function (ta, l)
for r=ta.maxr,0,-1 do if ta:validlr(l, r) then return r end end
end,
--
ne = function (ta, l, r) return lr(l, ta:calcmaxr(l)) end,
nw = function (ta, l, r) return lr(ta:calcmaxl(r), r) end,
--
cutunderl_ = function (ta, l)
local minr, maxr = ta:calcminr(l), ta:calcmaxr(l-1)
return format("%d%ds-%d%dn", l, minr, l-1, maxr)
end,
cutunder_r = function (ta, r)
local minl, maxl = ta:calcminl(r), ta:calcmaxl(r-1)
return format("%d%ds-%d%dn", minl, r, maxl, r-1)
end,
cutsunder = function (ta, str)
local cutsstr = ""
local addcut = function (str) cutsstr = cutsstr.." ".. str end
for l,r in str:gmatch("([0-9_])([0-9_])") do
if r == "_" and l+0 <= ta.maxl then addcut(ta:cutunderl_(l+0)) end
if l == "_" and r+0 <= ta.maxr then addcut(ta:cutunder_r(r+0)) end
end
return cutsstr
end,
--
contour = function (ta)
local minx,maxx = {}, {}
for y=0,ta:maxy() do minx[y] = ta:calcminx(y) end
for y=0,ta:maxy() do maxx[y] = ta:calcmaxx(y) end
local flipl = function (y) return minx[y+1] == minx[y-1] end
local flipr = function (y) return maxx[y+1] == maxx[y-1] end
local contourstr = "00s"
local addc = function (x, y, dir)
contourstr = contourstr .. "-" .. v(x,y):lr()..dir
end
for y=1,ta:maxy()-1 do if flipl(y) then addc(minx[y], y, "w") end end
contourstr = contourstr .. "-" .. ta.maxl..ta.maxr .. "n"
for y=ta:maxy()-1,1,-1 do if flipr(y) then addc(maxx[y], y, "e") end end
contourstr = contourstr .. "-00s"
return contourstr
end,
},
}
-- «TArrow-tests» (to ".TArrow-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "ZHA1.lua"
ta = TArrow.from("4,6; 32, 15 26")
= ta
= ta:getsquig() --> "123RRL43R21"
= ta:gettarrows() --> "46; 32, 15 26"
= ta:contour() --> "00s-20w-22w-42w-46n-26e-25e-15e-14e-04e-00s"
= ta:cutsunder("4_,_2") --> " 42s-36n 02s-21n"
= ta:newtop(3, 4)
= ta:getsquig() --> "123RRL21"
= ta:gettarrows() --> "34; 32,"
= ta:contour() --> "00s-20w-22w-32w-34n-04e-00s"
= ta:cutsunder("4_,_2") --> " 02s-21n"
ta = TArrow.from0("4,6; 32, 15 26")
= ta:drawrect().ap
= ta:erasearrows().ap
= ta:getsquig()
= ta:gettarrows()
-- (ph1p 29 "topologies-on-2CGs")
-- (ph1a "topologies-on-2CGs")
-- (ph1p 32 "topologies-on-2CGs")
-- (ph1a "topologies-on-2CGs" "disconnected")
ta = TArrow.from("34; 23, 22")
= ta
= ta:ne(1, 3):lr()
= ta:nw(0, 1):lr()
= ta:drawrect().ap
= ta:eraselrarrow(3,2).ap
= ta:eraserlarrow(2,4).ap
= ta:getsquig()
= ta:digit(2)
= ta:digit(1)
= ta:eraserect(3,1, 2,3).ap
--]]
-- ____ _
-- / ___| __ _ _ _(_) __ _
-- \___ \ / _` | | | | |/ _` |
-- ___) | (_| | |_| | | (_| |
-- |____/ \__, |\__,_|_|\__, |
-- |_| |___/
--
-- «Squig» (to ".Squig")
Squig = Class {
type = "Squig",
newlrw = function (L, R, W, char)
local l, r, w = L[#L], R[#R], W[#W]
if char == "L" then return l-1, r-1, w end
if char == "R" then return l+1, r+1, w end
if char+0 == w+1 then return l-1, r+1, w+1 end
if char+0 == w-1 then return l+1, r-1, w-1 end
PP("l r w char =", l, r, w, char)
error("Bad char!")
end,
getLRW = function (squig)
local L, R, W = {[0]=0}, {[0]=0}, {[0]=1}
for pos = 2,#squig do
local char = squig:sub(pos, pos)
local l,r,w = Squig.newlrw(L, R, W, char)
table.insert(L, l)
table.insert(R, r)
table.insert(W, w)
end
return L, R, W
end,
from = function (squig)
local L, R, W = Squig.getLRW(squig)
local minx = L[0]
local maxx = R[0]
for i=1,#L do minx = min(minx, L[i]) end
for i=1,#L do maxx = max(maxx, R[i]) end
local maxy = #squig - 1
local maxl,maxr = v(L[maxy], maxy):to_l_r()
return Squig {L=L, R=R, W=W, squig=squig,
minx=minx, maxx=maxx, maxy=maxy,
maxl=maxl, maxr=maxr}
end,
__tostring = function (sq) return sq:tostring() end,
__index = {
tostring = function (sq) return sq:draw():tostring() end,
draw = function (sq, ap)
ap = ap or AsciiPicture.new(" ")
for y=0,sq.maxy do
for x=sq.L[y],sq.R[y],2 do ap:putlr(v(x, y)) end
end
return ap
end,
gettarrows = function (sq)
local ta = TArrow { maxl=sq.maxl, maxr=sq.maxr, ap=sq:draw() }
return ta:gettarrows()
end,
},
}
-- «Squig-tests» (to ".Squig-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "ZHA1.lua"
PP(Squig.getLRW("12R1"))
PP(Squig.from("12R1"))
= Squig.from("12R1"):draw()
= TArrow.from("46; 32, 15 26")
= TArrow.from("46; 32, 15 26"):getsquig()
= Squig .from("123RRL43R21")
= Squig .from("123RRL43R21") :gettarrows()
--]]
-- (p2ap 1 "0._front-matter")
-- (p2aa "0._front-matter")
-- ______ _ _
-- |__ / | | | / \
-- / /| |_| | / _ \
-- / /_| _ |/ ___ \
-- /____|_| |_/_/ \_\
--
-- «ZHA» (to ".ZHA")
-- Adapted from: (find-dn6 "zhas.lua" "ZHA")
specwidths = function (spec)
local copydigit = function (s) return s:sub(1, 1):rep(#s) end
return (spec:gsub("[1-9][LRV]+", copydigit))
end
specx0 = function (spec) return -(ZHA.fromspec(spec).minx) end
ZHA = Class {
type = "ZHA",
fromspec = function (spec)
return ZHA.fromspec0(spec):calcminmaxlr()
end,
fromspec0 = function (spec, x0)
x0 = x0 or 0
local widths = specwidths(spec)
local z = ZHA {spec=spec, widths=widths,
maxy=#spec-1, minx=x0, maxx=x0,
L={[0]=x0}, R={[0]=x0}}
local getc = function (y) return spec :sub(y+1, y+1) end
local getw = function (y) return widths:sub(y+1, y+1)+0 end
local w, LR = 1, V{x0, x0}
local getdeltaLRw = function (y)
local c = getc(y)
if c == "L" then return V{-1, -1} end -- move left
if c == "R" then return V{ 1, 1} end -- move right
if c == (w+1).."" then w = w+1; return V{-1, 1} end -- become wider
if c == (w-1).."" then w = w-1; return V{ 1, -1} end -- become thinner
error("Bad char: "..c.." in spec: "..z.spec)
end
for y=1,z.maxy do
-- PP(y, getc(y), w)
-- LR = LR + PP(getdeltaLRw(y))
LR = LR + getdeltaLRw(y)
local xL, xR = LR[1], LR[2]
z.L[y], z.R[y] = xL, xR
z.minx = min(z.minx, xL)
z.maxx = max(z.maxx, xR)
end
return z
end,
--
-- A high-level method that uses the class LR in zhaspecs.lua.
-- See: (find-dn6 "zhaspecs.lua" "LR")
-- (find-dn6 "zhaspecs.lua" "LR" "fromtcgspec =")
-- (find-dn6 "zhaspecs.lua" "LR-fromtcgspec-tests")
fromtcgspec = function (spec)
return LR.fromtcgspec(spec):zha()
end,
--
__tostring = function (z) return z:tostring() end,
--
__index = {
-- PP = function (z) PP(z); return z end,
PP = function (z) print(mytabletostring(z)); return z end,
print = function (z) print(z); return z end,
hasxy = function (z, x,y)
local x, y = v(x, y):to12()
local L, R = z.L[y], z.R[y]
if not L then return false end
if not checkrange(L, x, R) then return false end
if not isint((x-L)/2) then return false end
return true
end,
xycontents = function (z, x,y)
local xy = v(x, y)
if z:hasxy(xy) then return xy:xytolr():todd() end
end,
tolines = function (z)
local lines = {}
for y=z.maxy,0,-1 do
local f = function (x) return z:xycontents(x, y) or " " end
table.insert(lines, mapconcat(f, seq(z.minx, z.maxx)))
end
return lines
end,
tostring = function (z) return table.concat(z:tolines(), "\n") end,
--
-- Compute minl[], maxl[], minr[], maxr[], lrtop
-- (find-dn6file "zha.lua" "calclrminmax =")
leftpoint = function (z, y) return v(z.L[y], y) end,
rightpoint = function (z, y) return v(z.R[y], y) end,
setminmaxlr0 = function (z, v)
local l, r = v:to_l_r()
z.minl[r], z.maxl[r] = minmax(z.minl[r], l, z.maxl[r])
z.minr[l], z.maxr[l] = minmax(z.minr[l], r, z.maxr[l])
end,
calcminmaxlr = function (z)
z.minl, z.minr, z.maxl, z.maxr = {}, {}, {}, {}
for y=0,z.maxy do
z:setminmaxlr0(z:leftpoint(y))
z:setminmaxlr0(z:rightpoint(y))
end
z.top = z:leftpoint(z.maxy)
z.topl, z.topr = z.top:to_l_r()
return z
end,
-- z:Imp(P,Q) uses ne and nw
sw = function (z, v) local l,r = v:to_l_r(); return lr(l, z.minr[l]) end,
ne = function (z, v) local l,r = v:to_l_r(); return lr(l, z.maxr[l]) end,
se = function (z, v) local l,r = v:to_l_r(); return lr(z.minl[r], r) end,
nw = function (z, v) local l,r = v:to_l_r(); return lr(z.maxl[r], r) end,
--
-- Generate all points and all arrows of the ZHA
points = function (z)
return cow(function ()
for l=z.topl,0,-1 do
for r=z.minr[l],z.maxr[l] do
coy(lr(l, r)) -- coy returns: lr(l,r)
end
end
end)
end,
arrows = function (z, usewhitemoves)
local tar = texarrow_smart(usewhitemoves)
return cow(function ()
for y=z.maxy,1,-1 do
for x=z.L[y],z.R[y],2 do
if z:hasxy(x-1, y-1) then coy(v(x, y), -1, -1, tar.sw) end
if z:hasxy(x+1, y-1) then coy(v(x, y), 1, -1, tar.se) end
-- coy returns: v(x,y), dx, dy, tex
end
end
end)
end,
--
-- For left generators, genp returns "L"; for right generators, "R"
genp = function (z, P)
local x,y = P:to_x_y()
if z.L[y] and z.L[y-1] then
local la,ma,ra = z.L[y], x, z.R[y] -- above
local lb,mb,rb = z.L[y-1], x, z.R[y-1] -- below
if la == ma and la + 1 == lb then return "L" end -- left gen
if ma == ra and rb + 1 == ra then return "R" end -- right gen
end
end,
pointslrg = function (z)
return cow(function ()
for P in z:points() do
local gen, l, r = z:genp(P), P:to_l_r()
coy(P, l, r, gen)
end
end)
end,
--
-- «ZHA-connectives» (to ".ZHA-connectives")
-- (to "ZHA-test-connectives")
-- Logical operations: <=, T, F, &, v, ->, <->, not
Le = function (z, P, Q) return P:below(Q) end,
T = function (z) return z.top end,
F = function (z) return V{0, 0} end,
And = function (z, P, Q) return P:And(Q) end,
Or = function (z, P, Q) return P:Or(Q) end,
Imp = function (z, P, Q)
if P:below(Q) then return z.top
elseif P:leftof(Q) then return z:ne(P:And(Q))
elseif P:rightof(Q) then return z:nw(P:And(Q))
else return Q
end
end,
Bic = function (z, P, Q) return z:And(z:Imp(P, Q), z:Imp(Q, P)) end,
Not = function (z, P) return z:Imp(P, z:F()) end,
--
-- «ZHA-getcuts» (to ".ZHA-getcuts")
-- See: (find-angg "LUA/lua50init.lua" "eval-and-L")
-- For a J-operator J, test the points of the upper-left and
-- upper-right walls to determine where are the cuts.
getcuts = function (z, J)
if type(J) == "string" then J = L(J) end
local cuts = ""
local add = function (c) cuts = cuts..c end
local ltoP = function (l) return lr(l, z.maxr[l]) end
local rtoP = function (r) return lr(z.maxl[r], r) end
local isstable = function (P) return J(P):lr() == P:lr() end
add(z.topl)
for l=z.topl-1,0,-1 do
if isstable(ltoP(l)) then add("/") end
add(l)
end
add(" ")
for r=0,z.topr-1 do
add(r)
if isstable(rtoP(r)) then add("|") end
end
add(z.topr)
return cuts
end,
--
-- «ZHA-walls» (to ".ZHA-walls")
-- (to "ZHA-tests-walls")
rightwallgenerators = function (z, all)
local A = {}
for r=1,z.topr do
if all or z.minl[r-1] < z.minl[r] then
table.insert(A, lr(z.minl[r], r))
end
end
return A
end,
leftwallgenerators = function (z, all)
local A = {}
for l=1,z.topl do
if all or z.minr[l-1] < z.minr[l] then
table.insert(A, lr(l, z.minr[l]))
end
end
return A
end,
totcgspec = function (z)
local maxl = z.topl
local maxr = z.topr
local tolr = function (v) return v:lr() end
local leftgens = mapconcat(tolr, z:leftwallgenerators(), " ")
local rightgens = mapconcat(tolr, z:rightwallgenerators(), " ")
return format("%s, %s; %s, %s", maxl, maxr, leftgens, rightgens)
end,
--
rightwallcorners = function (z)
local l, r = 0, 0
local A = {}
-- local dbg = function (str) PP(str, l, r) end
local push = function () table.insert(A, lr(l, r)) end
local nextoutercorner = function () r = z.maxr[l]; push() end
local nextinnercorner = function ()
if r < z.topr then l = z.minl[r+1]; push(); return true end
end
push()
nextoutercorner()
while nextinnercorner() do nextoutercorner() end
l, r = z.topl, z.topr
push()
return A
end,
leftwallcorners = function (z)
local l, r = 0, 0
local A = {}
-- local dbg = function (str) PP(str, l, r) end
local push = function () table.insert(A, lr(l, r)) end
local nextoutercorner = function () l = z.maxl[r]; push() end
local nextinnercorner = function ()
if l < z.topl then r = z.minr[l+1]; push(); return true end
end
push()
nextoutercorner()
while nextinnercorner() do nextoutercorner() end
l, r = z.topl, z.topr
push()
return A
end,
--
-- «ZHA-shrinktop» (to ".ZHA-shrinktop")
-- These methods use the class LR in zhaspecs.lua.
-- See: (find-dn6 "zhaspecs.lua" "LR")
toLR = function (z)
return LR.fromtcgspec(z:totcgspec())
end,
shrinktop = function (z, P)
return z:toLR():shrinktop(P):zha()
end,
},
}
-- «ZHA-tests» (to ".ZHA-tests")
--[[
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
ZHA.fromspec("12L1RRR2RL1"):PP():print()
ZHA.fromspec("123LLR432L1"):PP():print()
ZHA.fromspec("123RRL432R1"):PP():print()
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
-- dofile "zhaspecs.lua"
= ZHA.fromspec("123RRL432R1")
= ZHA.fromspec("123RRL432R1"):totcgspec()
= ZHA.fromtcgspec("4, 6; 32, 15 36") -- broken
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
z = ZHA.fromspec("123RRL432R1"):PP()
= z
for y=z.maxy-1,0,-1 do
for x=z.minx,z.maxx do
printf(z:xycontents(x, y) or " ")
end
print()
end
= z
z:PP()
PPV(z:tolines())
PP(z:tostring())
= z:hasxy(0,0)
= z
-- «ZHA-tests-walls» (to ".ZHA-tests-walls")
-- (to "ZHA-walls")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
-- (find-dn6 "zha.lua" "ZHA")
dofile "ZHA1.lua"
pris = function (o) printf("%s ", tostring(o)) end
z = ZHA.fromspec("12RRL1LLRR")
= z
for y=z.maxy,0,-1 do pris(z:leftpoint(y):lr()) end; print()
for y=z.maxy,0,-1 do pris(z:rightpoint(y):lr()) end; print()
for _,P in ipairs(z:rightwallgenerators("all")) do pris(P:lr()) end; print()
for _,P in ipairs(z:rightwallgenerators()) do pris(P:lr()) end; print()
for _,P in ipairs(z:leftwallgenerators("all")) do pris(P:lr()) end; print()
for _,P in ipairs(z:leftwallgenerators()) do pris(P:lr()) end; print()
for _,P in ipairs(z:rightwallcorners()) do pris(P:lr()) end; print()
for _,P in ipairs(z:leftwallcorners()) do pris(P:lr()) end; print()
-- 45
-- 44
-- 43
-- 33
-- 23
-- 22 13
-- 12 03
-- 11 02
-- 10 01
-- 00
-- «ZHA-test-connectives» (to ".ZHA-test-connectives")
-- (to "ZHA-connectives")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
-- (find-dn6 "zha.lua" "ZHA")
dofile "ZHA1.lua"
z = ZHA.fromspec("12RRL1LLRR"):print()
= z:Imp(v"11", v"02"):lr() --> 03
= z:Imp(v"03", v"12"):lr() --> 22
= z:Imp(v"23", v"12"):lr() --> 12
= z:Imp(v"12", v"23"):lr() --> 45
= z:ne(v"10"):lr() --> 13
= z:nw(v"02"):lr() --> 22
= v"12":And(v"03"):lr() --> 02
= v"11":And(v"02"):lr()
= z:ne(v"11":And(v"02")):lr() --> 03
= v("11"):leftof(v"02")
= v("11"):above(v"02")
= v("11"):below(v"02")
= v("23"):below(v"12")
= v("23"):above(v"12")
-- 45
-- 44
-- 43
-- 33
-- 23
-- 22 13
-- 12 03
-- 11 02
-- 10 01
-- 00
-- «ZHA-test-generators» (to ".ZHA-test-generators")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
z = ZHA.fromspec("123RRL432R1"):print()
for v in z:points() do printf("%s ", v:lr()) end; print()
-- Broken:
ap = AsciiPicture.new(" ")
for v in z:points() do ap:put(v, v:lr()) end
= ap
ap = AsciiPicture.new(" ")
for P in z:points() do ap:put(P, P:And(v"23"):lr()) end
= ap
z = ZHA.fromspec("121L"):print()
for P,dx,dy,tex in z:arrows() do print(P:lr().."->"..(P+v(dx,dy)):lr(), tex) end
-- «ZHA-test-shrinktop» (to ".ZHA-test-shrinktop")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
-- Broken:
dofile "zhas.lua"
dofile "zhaspecs.lua"
z = ZHA.fromtcgspec("4, 5; 32, 14 25"):print()
z = ZHA.fromtcgspec("4, 5; 32, 14 25"):shrinktop("34"):print()
--]]
-- _ _ _
-- ___| |__ ___ _ __| |_ ___ _ __ ___ _ __ __ _| |_ ___ _ __ ___
-- / __| '_ \ / _ \| '__| __/ _ \| '_ \ / _ \ '__/ _` | __/ _ \| '__/ __|
-- \__ \ | | | (_) | | | || (_) | |_) | __/ | | (_| | || (_) | | \__ \
-- |___/_| |_|\___/|_| \__\___/| .__/ \___|_| \__,_|\__\___/|_| |___/
-- |_|
-- «shortoperators» (to ".shortoperators")
function shortoperators ()
True = function () return z:T() end
False = function () return z:F() end
And = function (P, Q) return P:And(Q) end
Or = function (P, Q) return P:Or(Q) end
Imp = function (P, Q) return z:Imp(P, Q) end
Not = function (P) return Imp(P, False()) end
Bic = function (P, Q) return z:Bic(P, Q) end
--
Cloq = function (A) return function (P) return Or(A, P) end end
Opnq = function (A) return function (P) return Imp(A, P) end end
Booq = function (A) return function (P) return Imp(Imp(P, A), A) end end
Forq = function (A, B) return function (P) return And(Or(A, P), Imp(B, P)) end end
Jand = function (J, K) return function (P) return And(J(P), K(P)) end end
--
Mixq = function (A) return function (P) return Imp(Imp(P, A), P) end end
Mixq2 = function (A) return function (P) return Jand(Booq(A), Opnq(A))(P) end end
Truq = function () return function (P) return True() end end
Falq = function () return function (P) return P end end
end
-- «shortoperators-tests» (to ".shortoperators-tests")
--[[
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
shortoperators()
-- Broken:
= mpnewJ({}, "1234567654321", Opnq(v"23")):zhaPs("23")
= mpnewJ({}, "1234567654321", Cloq(v"23")):zhaPs("23")
= mpnewJ({}, "1234567654321", Booq(v"23")):zhaPs("23")
= mpnewJ({}, "1234567654321", Forq(v"42", v"24")):zhaPs("42 24")
= mpnewJ({}, "1234567654321", Jand(Booq(v"21"), Booq(v"12"))):zhaPs("21 12")
= mpnewJ({}, "1234567654321", Mixq (v"33")):zhaPs("33")
= mpnewJ({}, "1234567654321", Mixq2(v"33")):zhaPs("33")
= mpnewJ({}, "1234567654321", Truq()):zhaPs("")
= mpnewJ({}, "1234567654321", Falq()):zhaPs("")
--]]
-- _ ____
-- | | | _ \
-- | | | |_) |
-- | |___| _ <
-- |_____|_| \_\
--
-- «LR» (to ".LR")
-- Adapted from: (find-dn6 "zhaspecs.lua" "LR")
LR = Class {
type = "LR",
empty = function (maxy, ax)
return LR {L={}, R={}, maxy=maxy, ax=ax}
end,
from = function (L, R, maxy, ax)
return LR {L=L, R=R, maxy=maxy, ax=ax}
end,
fromspec = function (spec, x0, ax)
local z = ZHA.fromspec0(spec, x0)
return LR {L=z.L, R=z.R, ax=ax}
end,
fromtriples = function (A, maxy, ax)
local L, R = {}, {}
for _,triple in ipairs(A) do
local y, l, r = triple[1], triple[2], triple[3]
L[y], R[y] = l, (r or l)
end
return LR {L=L, R=R, maxy=maxy, ax=ax}
end,
--
-- 2-column graphs
-- See: (find-dn6 "tcgs.lua" "TCGSpec")
fromtcgspec = function (spec, ax)
-- local maxl,maxr,leftgens,rightgens = unpack(split(spec, "[ %d]+"))
local pat = "^ *(%d)[ ,]*(%d) *;([ %d]*),([ %d]*)$"
local maxl,maxr,leftgens,rightgens = spec:match(pat)
maxl,maxr = tonumber(maxl),tonumber(maxr)
return LR.fromtwocolgraph(maxl+0, maxr+0, leftgens, rightgens, ax)
end,
fromtwocolgraph = function (maxl, maxr, leftgens, rightgens, ax)
return LR.lozenge(maxl, maxr, ax):addgenerators(leftgens, rightgens)
end,
lozenge = function (maxl, maxr, ax)
local o = LR {L={}, R={}, ax=ax, maxl=maxl, maxr=maxr, maxy=maxl+maxr}
for y=0,maxl+maxr do
o.L[y] = o:nesex(-maxl, maxl, y)
o.R[y] = o:nwswx( maxr, maxr, y)
end
return o
end,
--
__tostring = function (o) return o:asciipicture():tostring() end,
__index = {
PP = function (o) print(mytabletostring(o)); return o end,
ap = function (o) return o:asciipicture() end,
asciipicture = function (o)
local ap = AsciiPicture.new(" ")
local put = function (x, y, n) ap:put(V{x, y}, n.."") end
for y=0,(o.maxy or #o.L) do
if o.L[y] then put(o.L[y], y, o.L[y]) end
if o.R[y] then put(o.R[y], y, o.R[y]) end
if o.ax then put(o.ax, y, y..":") end
end
return ap
end,
triples = function (o)
local A = {}
for y=(o.maxy or #o.L),0,-1 do
local l, r = o.L[y], o.R[y]
if l then table.insert(A, {y, l, r}) end
end
return A
end,
spec = function (o)
local W = {}
for y=0,#o.L do W[y] = toint((o.R[y] - o.L[y])/2) + 1 end
local spec = "1"
for y=1,#o.L do
if W[y] == W[y-1]
then spec = spec..((o.L[y]<o.L[y-1]) and "L" or "R")
else spec = spec..W[y]
end
end
return spec
end,
zha = function (o) return ZHA.fromspec(o:spec()) end,
--
-- putxy - see: (find-dn6 "luarects.lua" "ZHAFromPoints")
putxy = function (o, x, y)
o.L[y], o.R[y] = minmax(o.L[y], x, o.R[y])
return o
end,
--
-- addgenerators (for 2-column graphs)
swx = function (o, x0, y0, y1) return x0+(y1-y0) end,
nex = function (o, x0, y0, y1) return x0+(y1-y0) end,
sex = function (o, x0, y0, y1) return x0-(y1-y0) end,
nwx = function (o, x0, y0, y1) return x0-(y1-y0) end,
nesex = function (o, x0, y0, y1)
return y1>y0 and o:nex(x0, y0, y1) or o:sex(x0, y0, y1)
end,
nwswx = function (o, x0, y0, y1)
return y1>y0 and o:nwx(x0, y0, y1) or o:swx(x0, y0, y1)
end,
addleftpoint = function (o, x0, y0)
for y=0,o.maxy do o.L[y] = max(o.L[y], o:nwswx(x0, y0, y)) end
return o
end,
addrightpoint = function (o, x0, y0)
for y=0,o.maxy do o.R[y] = min(o.R[y], o:nesex(x0, y0, y)) end
return o
end,
addgenerators = function (o, leftstr, rightstr)
for leftgen in leftstr:gmatch"%d%d" do
local leftpoint = v(leftgen) + V{1,-1}
o:addleftpoint(leftpoint:to_x_y())
end
for rightgen in rightstr:gmatch"%d%d" do
local rightpoint = v(rightgen) + V{-1,-1}
o:addrightpoint(rightpoint:to_x_y())
end
return o
end,
--
shrinktop = function (o, newtop)
newtop = v(newtop)
local x1, y1 = newtop[1], newtop[2]
if not (y1 <= o.maxy) then return o end
if not (o.L[y1] <= x1 and x1 <= o.R[y1]) then return o end
for y=o.maxy,y1+1,-1 do
o.L[y] = nil
o.R[y] = nil
end
o.maxy = y1
for dy=0,y1 do
local y, xl, xr = y1-dy, x1-dy, x1+dy
o.L[y] = max(o.L[y], xl)
o.R[y] = min(o.R[y], xr)
end
return o
end,
},
}
-- «LR-tests» (to ".LR-tests")
--[[
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
A = {{5, 1 },
{4, 2 },
{3, 1,3 },
{2, 0, 4 },
{1, 1,3 },
{0, 2 }}
= LR.fromtriples(A, nil) -- Broken
= LR.fromtriples(A, nil, -2)
= LR.fromtriples(A, nil, -4)
o = LR.fromtriples(A, nil, -2)
= o
= o:PP()
= o:spec()
= o:zha():PP()
= LR.fromspec("123RR21RL")
= LR.fromspec("123RR21RL", nil, -4)
= LR.fromspec("123RR21RL", 0, -4)
= LR.fromspec("123RR21RL", 1, -4)
= LR.fromspec("123RR21RL", 2, -4)
PPV(LR.fromspec("123RR21RL", 2, -4):triples())
-- «LR-putxy-tests» (to ".LR-putxy-tests")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
require "picture"
require "zhas"
f = function (y, str)
for x,c in str:gmatch"()(%S)" do o:putxy(x, y) end
return o
end
o = LR.from({}, {}, 5, -2)
= o
= f(5, " o ")
= f(4, " o ")
= f(3, " o o ")
= f(2, "o o o")
= f(1, " o o ")
= f(0, " o ")
= o:zha()
-- «LR-twocolgraph-tests» (to ".LR-twocolgraph-tests")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "zhaspecs.lua"
require "picture"
require "zhas"
= LR.lozenge(2, 4)
= LR.lozenge(4, 6)
= LR.lozenge(4, 6, -6)
= LR.lozenge(4, 6):zha()
= LR.lozenge(4, 6):addgenerators("32", ""):zha()
= LR.lozenge(4, 6):addgenerators("32", "15"):zha()
= LR.lozenge(4, 6):addgenerators("32", "15 26"):zha()
= LR.fromtwocolgraph(4, 6, "", "" ):zha()
= LR.fromtwocolgraph(4, 6, "32", "" ):zha()
= LR.fromtwocolgraph(4, 6, "32", "15" ):zha()
= LR.fromtwocolgraph(4, 6, "32", "15 26"):zha()
= LR.fromtcgspec(" 4, 6; , "):zha()
= LR.fromtcgspec(" 4, 6; 32, "):zha()
= LR.fromtcgspec(" 4, 6; 32, 15 "):zha()
= LR.fromtcgspec(" 4, 6; 32, 15 26"):zha()
= LR.fromtcgspec(" 4, 6; 32, 15 26"):zha().spec
= LR.fromtcgspec(" 4, 6; 32, 15 26"):zha():totcgspec()
= LR.fromtcgspec( "46; 32, 15 26"):zha():totcgspec()
-- «LR-fromtcgspec-tests» (to ".LR-fromtcgspec-tests")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "zhaspecs.lua"
require "picture"
require "zhas"
= LR.fromtcgspec("4, 6; 11 22 34 45, 25"):zha()
= LR.fromtcgspec("4, 6; 11 22 34 45, 25"):zha().spec
= LR.fromtcgspec("4, 6; 11 22 34 45, 25"):zha():totcgspec()
= LR.fromtcgspec("4, 6; 11 22 34 45, 25 06"):zha()
= LR.fromtcgspec("4, 6; 11 22 34 45, 25 06"):zha():totcgspec()
-- «LR-shrinktop-tests» (to ".LR-shrinktop-tests")
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "zhaspecs.lua"
require "picture"
require "zhas"
o = LR.fromtcgspec("4, 6; 11 22 34 45, 25 06")
= o:zha()
= o:shrinktop(v"47"):zha()
= o:shrinktop( "35"):zha()
--]]
-- -- _ _ _ ____ _ _
-- -- / \ ___ ___(_|_) _ \(_) ___| |_ _ _ _ __ ___
-- -- / _ \ / __|/ __| | | |_) | |/ __| __| | | | '__/ _ \
-- -- / ___ \\__ \ (__| | | __/| | (__| |_| |_| | | | __/
-- -- /_/ \_\___/\___|_|_|_| |_|\___|\__|\__,_|_| \___|
-- --
-- -- «AsciiPicture» (to ".AsciiPicture")
-- -- From: (find-dn6 "picture.lua" "AsciiPicture")
-- -- This is a minimalistic, and V-based, reimplementation of the
-- -- ascii side of the "Picture" class from:
-- -- (find-dn6 "picture.lua" "Picture")
--
-- AsciiPicture = Class {
-- type = "AsciiPicture",
-- new = function (s)
-- return AsciiPicture {s=s or " ", bb=BoundingBox.new()}
-- end,
-- __tostring = function (ap) return ap:tostring() end,
-- __index = {
-- get = function (ap, v) return pad(ap.s, ap:get0(v)) end,
-- get0 = function (ap, v)
-- local x, y = v:to_x_y()
-- return ap[y] and ap[y][x]
-- end,
-- put = function (ap, v, str)
-- local x, y = v:to_x_y()
-- ap[y] = ap[y] or {}
-- ap[y][x] = str
-- ap.bb:addpoint(v)
-- return ap
-- end,
-- --
-- tolines = function (ap)
-- if not ap.bb.x0y0 then return {} end -- empty
-- local x0, x1, y0, y1 = ap.bb:x0x1y0y1()
-- local lines = {}
-- for y=y1,y0,-1 do
-- local line = ""
-- for x=x0,x1 do line = line..ap:get(v(x, y)) end
-- table.insert(lines, line)
-- end
-- return lines
-- end,
-- tostring = function (ap) return table.concat(ap:tolines(), "\n") end,
-- print = function (ap) print(ap); return ap end,
-- },
-- }
-- «AsciiPicture-tests» (to ".AsciiPicture-tests")
--[[
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
ap = AsciiPicture.new(" ")
ap = AsciiPicture.new(" ")
ap = AsciiPicture.new(" ")
for l=0,2 do
for r=0,3 do
local pos=lr(l, r)
ap:put(pos, "..")
ap:put(pos, pos:lr())
ap:put(pos, pos:xy())
end
end
= ap
PPV(ap)
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
ap = AsciiPicture.new(" ")
PP(ap)
PP(ap.bb)
= ap
= ap.bb
ap = AsciiPicture.new(" "):put(v(1,1)," ")
= ap
= ap:put(v(1,1), "..")
= ap
= ap.bb
PP(ap)
--]]
-- _
-- ___ ___ _ __ _ _ ___ _ __ | |_ ___
-- / __/ _ \| '_ \| | | |/ _ \| '_ \| __/ __|
-- | (_| (_) | |_) | |_| | (_) | |_) | |_\__ \
-- \___\___/| .__/ \__, |\___/| .__/ \__|___/
-- |_| |___/ |_|
--
-- An _UGLY_ hack to let me specify options for makepicture in a compact way.
-- A call to copyopts(A, B) copies the options in the table A to the table B.
-- If there is a field "meta" in A it is treated in a special way:
--
-- copyopts({foo=2, bar=3, meta="s ()"}, B)
--
-- works as this, but in an unspecified order:
--
-- copyopts({foo=2, bar=3}, B)
-- copyopts(metaopts["s"], B)
-- copyopts(metaopts["()"], B)
--
-- Used by: (find-dn6 "zhas.lua" "MixedPicture" "LPicture.new(options)")
-- (find-dn6 "picture.lua" "LPicture" "new" "copyopts(opts, lp)")
--
-- «copyopts» (to ".copyopts")
--
copyopts = function (A, B)
if type(A) == "string" then
for _,name in ipairs(split(A)) do
local tbl = metaopts[name] or error("No metaopt[\""..A.."\"]")
copyopts(tbl, B)
end
return B
end
for key,val in pairs(A) do
if key == "meta" then
copyopts(val, B)
else
B[key] = val
end
end
return B
end
-- «metaopts» (to ".metaopts")
--
metaopts = {}
metaopts["b"] = {bhbox = 1}
metaopts["p"] = {paren = 1}
metaopts["()"] = {paren = 1}
metaopts["{}"] = {curly = 1}
metaopts["s"] = {cellfont="\\scriptsize", celllower="2pt"}
metaopts["ss"] = {cellfont="\\scriptscriptsize", celllower="1.5pt"} -- ?
metaopts["t"] = {cellfont="\\tiny", celllower="1.5pt"} -- ?
metaopts["t"] = {cellfont="\\tiny", celllower="1.25pt"} -- ?
metaopts["10pt"] = {scale="10pt"}
metaopts["8pt"] = {scale="8pt", meta="s"}
--
-- metaopts that are mainly for TCGs:
metaopts["1pt"] = {scale="1pt"}
-- «copyopts-tests» (to ".copyopts-tests")
--[[
• (eepitch-lua51)
• (eepitch-kill)
• (eepitch-lua51)
dofile "ZHA1.lua"
testcopyopts = function (A) PP(copyopts(A, {})) end
testcopyopts "8pt"
testcopyopts "8pt ()"
testcopyopts {foo=2, bar=3}
testcopyopts {foo=2, bar=3, meta="8pt"}
testcopyopts {foo=2, bar=3, meta="8pt ()"}
testcopyopts {foo=2, bar=3}
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: