# Copyright (C) 2016, 2017, 2018  Stefan Vargyas
# 
# This file is part of Json-Type.
# 
# Json-Type is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# Json-Type is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Json-Type.  If not, see <http://www.gnu.org/licenses/>.

#
# json trie test suite:
#

$ . ~/regtest2.sh
$ alias json-trie-regtest='regtest2-selftest -f test-json-trie.txt -a exec=pipe -B'

# output all test names:
$ json-trie-regtest -N
...

# run all tests:
$ json-trie-regtest -A
...

--[ prereq ]--------------------------------------------------------------------

$ test -x ../lib/test-trie
$ print() { printf '%s\n' "$@"; }
$ set -o pipefail
$

--[ empty ]---------------------------------------------------------------------

$ test-trie() { ../lib/test-trie -T; }
$ echo -n|test-trie
trie=null
$ print|test-trie
trie={"val":"","lo":null,"hi":null}
node={"val":"","lo":null,"hi":null}
char='\0'
$

--[ base ]----------------------------------------------------------------------

$ test-trie() { ../lib/test-trie -T; }
$ print a b|test-trie
trie={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null}}
node={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null}}
char='a'
char='b'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
$ print b a|test-trie
trie={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":null}
node={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":null}
char='a'
char='b'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
$ print a b c|test-trie
trie={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}}
node={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print b c a|test-trie
trie={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
node={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print c b a|test-trie
trie={"sym":"c","lo":{"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":null},"eq":{"val":"c","lo":null,"hi":null},"hi":null}
node={"sym":"c","lo":{"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":null},"eq":{"val":"c","lo":null,"hi":null},"hi":null}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print a c b|test-trie
trie={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"c","lo":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null},"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
node={"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"c","lo":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null},"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print b a c|test-trie
trie={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
node={"sym":"b","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":null},"eq":{"val":"b","lo":null,"hi":null},"hi":{"sym":"c","lo":null,"eq":{"val":"c","lo":null,"hi":null},"hi":null}}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print c a b|test-trie
trie={"sym":"c","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null}},"eq":{"val":"c","lo":null,"hi":null},"hi":null}
node={"sym":"c","lo":{"sym":"a","lo":null,"eq":{"val":"a","lo":null,"hi":null},"hi":{"sym":"b","lo":null,"eq":{"val":"b","lo":null,"hi":null},"hi":null}},"eq":{"val":"c","lo":null,"hi":null},"hi":null}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print ab|test-trie
trie={"sym":"a","lo":null,"eq":{"sym":"b","lo":null,"eq":{"val":"ab","lo":null,"hi":null},"hi":null},"hi":null}
node={"sym":"a","lo":null,"eq":{"sym":"b","lo":null,"eq":{"val":"ab","lo":null,"hi":null},"hi":null},"hi":null}
char='a'
node={"sym":"b","lo":null,"eq":{"val":"ab","lo":null,"hi":null},"hi":null}
char='b'
node={"val":"ab","lo":null,"hi":null}
char='\0'
$ print z ax abc abd aef aeg|test-trie
trie={"sym":"z","lo":{"sym":"a","lo":null,"eq":{"sym":"x","lo":{"sym":"b","lo":null,"eq":{"sym":"c","lo":null,"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"hi":{"sym":"e","lo":null,"eq":{"sym":"f","lo":null,"eq":{"val":"aef","lo":null,"hi":null},"hi":{"sym":"g","lo":null,"eq":{"val":"aeg","lo":null,"hi":null},"hi":null}},"hi":null}},"eq":{"val":"ax","lo":null,"hi":null},"hi":null},"hi":null},"eq":{"val":"z","lo":null,"hi":null},"hi":null}
node={"sym":"z","lo":{"sym":"a","lo":null,"eq":{"sym":"x","lo":{"sym":"b","lo":null,"eq":{"sym":"c","lo":null,"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"hi":{"sym":"e","lo":null,"eq":{"sym":"f","lo":null,"eq":{"val":"aef","lo":null,"hi":null},"hi":{"sym":"g","lo":null,"eq":{"val":"aeg","lo":null,"hi":null},"hi":null}},"hi":null}},"eq":{"val":"ax","lo":null,"hi":null},"hi":null},"hi":null},"eq":{"val":"z","lo":null,"hi":null},"hi":null}
char='a'
char='z'
node={"sym":"x","lo":{"sym":"b","lo":null,"eq":{"sym":"c","lo":null,"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"hi":{"sym":"e","lo":null,"eq":{"sym":"f","lo":null,"eq":{"val":"aef","lo":null,"hi":null},"hi":{"sym":"g","lo":null,"eq":{"val":"aeg","lo":null,"hi":null},"hi":null}},"hi":null}},"eq":{"val":"ax","lo":null,"hi":null},"hi":null}
char='b'
char='e'
char='x'
node={"val":"z","lo":null,"hi":null}
char='\0'
node={"sym":"c","lo":null,"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}}
char='c'
char='d'
node={"sym":"f","lo":null,"eq":{"val":"aef","lo":null,"hi":null},"hi":{"sym":"g","lo":null,"eq":{"val":"aeg","lo":null,"hi":null},"hi":null}}
char='f'
char='g'
node={"val":"ax","lo":null,"hi":null}
char='\0'
node={"val":"abc","lo":null,"hi":null}
char='\0'
node={"val":"abd","lo":null,"hi":null}
char='\0'
node={"val":"aef","lo":null,"hi":null}
char='\0'
node={"val":"aeg","lo":null,"hi":null}
char='\0'
$ print aef ae abg a abc ab abd|test-trie
trie={"sym":"a","lo":null,"eq":{"sym":"e","lo":{"sym":"b","lo":{"val":"a","lo":null,"hi":null},"eq":{"sym":"g","lo":{"sym":"c","lo":{"val":"ab","lo":null,"hi":null},"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"eq":{"val":"abg","lo":null,"hi":null},"hi":null},"hi":null},"eq":{"sym":"f","lo":{"val":"ae","lo":null,"hi":null},"eq":{"val":"aef","lo":null,"hi":null},"hi":null},"hi":null},"hi":null}
node={"sym":"a","lo":null,"eq":{"sym":"e","lo":{"sym":"b","lo":{"val":"a","lo":null,"hi":null},"eq":{"sym":"g","lo":{"sym":"c","lo":{"val":"ab","lo":null,"hi":null},"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"eq":{"val":"abg","lo":null,"hi":null},"hi":null},"hi":null},"eq":{"sym":"f","lo":{"val":"ae","lo":null,"hi":null},"eq":{"val":"aef","lo":null,"hi":null},"hi":null},"hi":null},"hi":null}
char='a'
node={"sym":"e","lo":{"sym":"b","lo":{"val":"a","lo":null,"hi":null},"eq":{"sym":"g","lo":{"sym":"c","lo":{"val":"ab","lo":null,"hi":null},"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"eq":{"val":"abg","lo":null,"hi":null},"hi":null},"hi":null},"eq":{"sym":"f","lo":{"val":"ae","lo":null,"hi":null},"eq":{"val":"aef","lo":null,"hi":null},"hi":null},"hi":null}
char='\0'
char='b'
char='e'
node={"sym":"g","lo":{"sym":"c","lo":{"val":"ab","lo":null,"hi":null},"eq":{"val":"abc","lo":null,"hi":null},"hi":{"sym":"d","lo":null,"eq":{"val":"abd","lo":null,"hi":null},"hi":null}},"eq":{"val":"abg","lo":null,"hi":null},"hi":null}
char='\0'
char='c'
char='d'
char='g'
node={"sym":"f","lo":{"val":"ae","lo":null,"hi":null},"eq":{"val":"aef","lo":null,"hi":null},"hi":null}
char='\0'
char='f'
node={"val":"abc","lo":null,"hi":null}
char='\0'
node={"val":"abd","lo":null,"hi":null}
char='\0'
node={"val":"abg","lo":null,"hi":null}
char='\0'
node={"val":"aef","lo":null,"hi":null}
char='\0'
$

--[ shuf ]----------------------------------------------------------------------

$ test-trie() { shuf|../lib/test-trie -T|sed -r '1{s/^(trie=).*$/\1{...}/;b};/^node=\{"val":"[^"]+","lo":null,"hi":null\}$/b;s/^(node=\{).*(\})$/\1...\2/'; }
$ print a b|test-trie
trie={...}
node={...}
char='a'
char='b'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
$ print a b c|test-trie
trie={...}
node={...}
char='a'
char='b'
char='c'
node={"val":"a","lo":null,"hi":null}
char='\0'
node={"val":"b","lo":null,"hi":null}
char='\0'
node={"val":"c","lo":null,"hi":null}
char='\0'
$ print z ax abc abd aef aeg|test-trie
trie={...}
node={...}
char='a'
char='z'
node={...}
char='b'
char='e'
char='x'
node={"val":"z","lo":null,"hi":null}
char='\0'
node={...}
char='c'
char='d'
node={...}
char='f'
char='g'
node={"val":"ax","lo":null,"hi":null}
char='\0'
node={"val":"abc","lo":null,"hi":null}
char='\0'
node={"val":"abd","lo":null,"hi":null}
char='\0'
node={"val":"aef","lo":null,"hi":null}
char='\0'
node={"val":"aeg","lo":null,"hi":null}
char='\0'
$ print aef ae abg a abc ab abd|test-trie
trie={...}
node={...}
char='a'
node={...}
char='\0'
char='b'
char='e'
node={...}
char='\0'
char='c'
char='d'
char='g'
node={...}
char='\0'
char='f'
node={"val":"abc","lo":null,"hi":null}
char='\0'
node={"val":"abd","lo":null,"hi":null}
char='\0'
node={"val":"abg","lo":null,"hi":null}
char='\0'
node={"val":"aef","lo":null,"hi":null}
char='\0'
$

--[ depths ]--------------------------------------------------------------------

$ test-trie() { ../lib/test-trie -D; }
$ print|test-trie
iter:     1
sib-iter: 1
lvl-iter: 1
$ print a b|test-trie
iter:     3
sib-iter: 2
lvl-iter: 2
$ print b a|test-trie
iter:     3
sib-iter: 2
lvl-iter: 2
$ print a b c|test-trie
iter:     4
sib-iter: 3
lvl-iter: 3
$ print b c a|test-trie
iter:     3
sib-iter: 2
lvl-iter: 3
$ print c b a|test-trie
iter:     4
sib-iter: 3
lvl-iter: 3
$ print a c b|test-trie
iter:     4
sib-iter: 3
lvl-iter: 3
$ print b a c|test-trie
iter:     3
sib-iter: 2
lvl-iter: 3
$ print c a b|test-trie
iter:     4
sib-iter: 3
lvl-iter: 3
$ print ab|test-trie
iter:     3
sib-iter: 1
lvl-iter: 1
$ print z ax abc abd aef aeg|test-trie
iter:     8
sib-iter: 2
lvl-iter: 6
$ print aef ae abg a abc ab abd|test-trie
iter:     7
sib-iter: 1
lvl-iter: 7
$ print '' a|test-trie
iter:     3
sib-iter: 2
lvl-iter: 2
$ print aw ax by bz|test-trie
iter:     5
sib-iter: 2
lvl-iter: 4
$

--[ sgb-words ]-----------------------------------------------------------------

$ wc -l < sgb-words.txt
5757
$ test-trie() { set -o pipefail && ../lib/test-trie -p 2M -D < sgb-words.txt; }
$ test-trie
iter:     29
sib-iter: 14
lvl-iter: 5757
$ test-trie() { set -o pipefail && ../lib/test-trie -p 2M -T "$@" < sgb-words.txt 2>&1 >/dev/null|sed -r '/fatal error:/{s|(fatal error: )\s*\./+|\1|;s/:[0-9]+:/:???:/}'; }
$ test-trie -l 5756
test-trie: fatal error: trie-impl.h:???:test_trie_lvl_iterator_inc: stack overflow
command failed: test-trie -l 5756
$ test-trie -l 5757
$

--[ rebalance ]-----------------------------------------------------------------

$ json() { env LD_LIBRARY_PATH=../lib ../src/json --no-error "$@" || return 0; }
$ test-trie() { local u=''; [ "$1" == '-u' ] && { u='u'; shift; }; ../lib/test-trie -R|sed -${u:+n}r ${u:+'H;$! b;g;s/^\n//;'}'s/,?"(lo|hi)":null//g'${u:+';s/^([^\n]+)\n\1$/\1/;p'}|json -Po -m; }
$ print '' a|test-trie
{
.   "val": "",
.   "hi": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   }
}
{
.   "sym": "a",
.   "lo": {
.   .   "val": ""
.   },
.   "eq": {
.   .   "val": "a"
.   }
}
$ print a ''|test-trie -u
{
.   "sym": "a",
.   "lo": {
.   .   "val": ""
.   },
.   "eq": {
.   .   "val": "a"
.   }
}
$ print a b|test-trie
{
.   "sym": "a",
.   "eq": {
.   .   "val": "a"
.   },
.   "hi": {
.   .   "sym": "b",
.   .   "eq": {
.   .   .   "val": "b"
.   .   }
.   }
}
{
.   "sym": "b",
.   "lo": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   },
.   "eq": {
.   .   "val": "b"
.   }
}
$ print b a|test-trie -u
{
.   "sym": "b",
.   "lo": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   },
.   "eq": {
.   .   "val": "b"
.   }
}
$ print a b c|test-trie
{
.   "sym": "a",
.   "eq": {
.   .   "val": "a"
.   },
.   "hi": {
.   .   "sym": "b",
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "b",
.   "lo": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   },
.   "eq": {
.   .   "val": "b"
.   },
.   "hi": {
.   .   "sym": "c",
.   .   "eq": {
.   .   .   "val": "c"
.   .   }
.   }
}
$ print c b a|test-trie
{
.   "sym": "c",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   }
.   },
.   "eq": {
.   .   "val": "c"
.   }
}
{
.   "sym": "b",
.   "lo": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   },
.   "eq": {
.   .   "val": "b"
.   },
.   "hi": {
.   .   "sym": "c",
.   .   "eq": {
.   .   .   "val": "c"
.   .   }
.   }
}
$ print b a c|test-trie -u
{
.   "sym": "b",
.   "lo": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "a"
.   .   }
.   },
.   "eq": {
.   .   "val": "b"
.   },
.   "hi": {
.   .   "sym": "c",
.   .   "eq": {
.   .   .   "val": "c"
.   .   }
.   }
}
$ print a b c d|test-trie
{
.   "sym": "a",
.   "eq": {
.   .   "val": "a"
.   },
.   "hi": {
.   .   "sym": "b",
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "d",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "d"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "c",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   }
.   },
.   "eq": {
.   .   "val": "c"
.   },
.   "hi": {
.   .   "sym": "d",
.   .   "eq": {
.   .   .   "val": "d"
.   .   }
.   }
}
$ print d c b a|test-trie
{
.   "sym": "d",
.   "lo": {
.   .   "sym": "c",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "a"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "b"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "c"
.   .   }
.   },
.   "eq": {
.   .   "val": "d"
.   }
}
{
.   "sym": "c",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   }
.   },
.   "eq": {
.   .   "val": "c"
.   },
.   "hi": {
.   .   "sym": "d",
.   .   "eq": {
.   .   .   "val": "d"
.   .   }
.   }
}
$ print c b a d|test-trie -u
{
.   "sym": "c",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   }
.   },
.   "eq": {
.   .   "val": "c"
.   },
.   "hi": {
.   .   "sym": "d",
.   .   "eq": {
.   .   .   "val": "d"
.   .   }
.   }
}
$ print a b c d e|test-trie
{
.   "sym": "a",
.   "eq": {
.   .   "val": "a"
.   },
.   "hi": {
.   .   "sym": "b",
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "d",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "d"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "e",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "e"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "d",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   }
.   .   }
.   },
.   "eq": {
.   .   "val": "d"
.   },
.   "hi": {
.   .   "sym": "e",
.   .   "eq": {
.   .   .   "val": "e"
.   .   }
.   }
}
$ print e d c b a|test-trie
{
.   "sym": "e",
.   "lo": {
.   .   "sym": "d",
.   .   "lo": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "a"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "b"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "d"
.   .   }
.   },
.   "eq": {
.   .   "val": "e"
.   }
}
{
.   "sym": "d",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   }
.   .   }
.   },
.   "eq": {
.   .   "val": "d"
.   },
.   "hi": {
.   .   "sym": "e",
.   .   "eq": {
.   .   .   "val": "e"
.   .   }
.   }
}
$ print d b c a e|test-trie -u
{
.   "sym": "d",
.   "lo": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "a"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "b"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "c"
.   .   .   }
.   .   }
.   },
.   "eq": {
.   .   "val": "d"
.   },
.   "hi": {
.   .   "sym": "e",
.   .   "eq": {
.   .   .   "val": "e"
.   .   }
.   }
}
$ print x xa|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "val": "x",
.   .   "hi": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "lo": {
.   .   .   "val": "x"
.   .   },
.   .   "eq": {
.   .   .   "val": "xa"
.   .   }
.   }
}
$ print xa x|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "lo": {
.   .   .   "val": "x"
.   .   },
.   .   "eq": {
.   .   .   "val": "xa"
.   .   }
.   }
}
$ print xa xb|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "xa"
.   .   },
.   .   "hi": {
.   .   .   "sym": "b",
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xb"
.   .   }
.   }
}
$ print xb xa|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xb"
.   .   }
.   }
}
$ print xa xb xc|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "xa"
.   .   },
.   .   "hi": {
.   .   .   "sym": "b",
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xb"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "xc"
.   .   .   }
.   .   }
.   }
}
$ print xc xb xa|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "c",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xc"
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xb"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "xc"
.   .   .   }
.   .   }
.   }
}
$ print xb xa xc|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xa"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xb"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "xc"
.   .   .   }
.   .   }
.   }
}
$ print xa xb xc xd|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "xa"
.   .   },
.   .   "hi": {
.   .   .   "sym": "b",
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "d",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xd"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "c",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xc"
.   .   },
.   .   "hi": {
.   .   .   "sym": "d",
.   .   .   "eq": {
.   .   .   .   "val": "xd"
.   .   .   }
.   .   }
.   }
}
$ print xd xc xb xa|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "d",
.   .   "lo": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xa"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xb"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xc"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xd"
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "c",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xc"
.   .   },
.   .   "hi": {
.   .   .   "sym": "d",
.   .   .   "eq": {
.   .   .   .   "val": "xd"
.   .   .   }
.   .   }
.   }
}
$ print xc xb xa xd|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "c",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xc"
.   .   },
.   .   "hi": {
.   .   .   "sym": "d",
.   .   .   "eq": {
.   .   .   .   "val": "xd"
.   .   .   }
.   .   }
.   }
}
$ print xa xb xc xd xe|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "xa"
.   .   },
.   .   "hi": {
.   .   .   "sym": "b",
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "d",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xd"
.   .   .   .   .   },
.   .   .   .   .   "hi": {
.   .   .   .   .   .   "sym": "e",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xe"
.   .   .   .   .   .   }
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "d",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xd"
.   .   },
.   .   "hi": {
.   .   .   "sym": "e",
.   .   .   "eq": {
.   .   .   .   "val": "xe"
.   .   .   }
.   .   }
.   }
}
$ print xe xd xc xb xa|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "e",
.   .   "lo": {
.   .   .   "sym": "d",
.   .   .   "lo": {
.   .   .   .   "sym": "c",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "b",
.   .   .   .   .   "lo": {
.   .   .   .   .   .   "sym": "a",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xa"
.   .   .   .   .   .   }
.   .   .   .   .   },
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xb"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xd"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xe"
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "d",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xd"
.   .   },
.   .   "hi": {
.   .   .   "sym": "e",
.   .   .   "eq": {
.   .   .   .   "val": "xe"
.   .   .   }
.   .   }
.   }
}
$ print xd xb xc xa xe|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "d",
.   .   "lo": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "xd"
.   .   },
.   .   "hi": {
.   .   .   "sym": "e",
.   .   .   "eq": {
.   .   .   .   "val": "xe"
.   .   .   }
.   .   }
.   }
}
$ print xy xya|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "val": "xy",
.   .   .   "hi": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "lo": {
.   .   .   .   "val": "xy"
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   }
.   .   }
.   }
}
$ print xya xy|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "lo": {
.   .   .   .   "val": "xy"
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   }
.   .   }
.   }
}
$ print xya xyb|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "b",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyb"
.   .   .   }
.   .   }
.   }
}
$ print xyb xya|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyb"
.   .   .   }
.   .   }
.   }
}
$ print xya xyb xyc|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "b",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xyc xyb xya|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyc"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xyb xya xyc|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xya"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xya xyb xyc xyd|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "b",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   },
.   .   .   .   .   "hi": {
.   .   .   .   .   .   "sym": "d",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xyd"
.   .   .   .   .   .   }
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyc"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "d",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyd"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xyd xyc xyb xya|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "d",
.   .   .   "lo": {
.   .   .   .   "sym": "c",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "b",
.   .   .   .   .   "lo": {
.   .   .   .   .   .   "sym": "a",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xya"
.   .   .   .   .   .   }
.   .   .   .   .   },
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyb"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyc"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyd"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyc"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "d",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyd"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xyc xyb xya xyd|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "c",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyc"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "d",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyd"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xya xyb xyc xyd xye|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "xya"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "b",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   },
.   .   .   .   .   "hi": {
.   .   .   .   .   .   "sym": "d",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xyd"
.   .   .   .   .   .   },
.   .   .   .   .   .   "hi": {
.   .   .   .   .   .   .   "sym": "e",
.   .   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   .   "val": "xye"
.   .   .   .   .   .   .   }
.   .   .   .   .   .   }
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "d",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyd"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "e",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xye"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xye xyd xyc xyb xya|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "e",
.   .   .   "lo": {
.   .   .   .   "sym": "d",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "lo": {
.   .   .   .   .   .   "sym": "b",
.   .   .   .   .   .   "lo": {
.   .   .   .   .   .   .   "sym": "a",
.   .   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   .   "val": "xya"
.   .   .   .   .   .   .   }
.   .   .   .   .   .   },
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "xyb"
.   .   .   .   .   .   }
.   .   .   .   .   },
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyd"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xye"
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "d",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyd"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "e",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xye"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xyd xyb xyc xya xye|test-trie -u
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "d",
.   .   .   "lo": {
.   .   .   .   "sym": "b",
.   .   .   .   "lo": {
.   .   .   .   .   "sym": "a",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xya"
.   .   .   .   .   }
.   .   .   .   },
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xyb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "xyc"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xyd"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "e",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xye"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print xa xb xc ya yb yc za zb zc|test-trie
{
.   "sym": "x",
.   "eq": {
.   .   "sym": "a",
.   .   "eq": {
.   .   .   "val": "xa"
.   .   },
.   .   "hi": {
.   .   .   "sym": "b",
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   }
.   },
.   "hi": {
.   .   "sym": "y",
.   .   "eq": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "ya"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "b",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "yb"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "c",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "yc"
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   },
.   .   "hi": {
.   .   .   "sym": "z",
.   .   .   "eq": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "za"
.   .   .   .   },
.   .   .   .   "hi": {
.   .   .   .   .   "sym": "b",
.   .   .   .   .   "eq": {
.   .   .   .   .   .   "val": "zb"
.   .   .   .   .   },
.   .   .   .   .   "hi": {
.   .   .   .   .   .   "sym": "c",
.   .   .   .   .   .   "eq": {
.   .   .   .   .   .   .   "val": "zc"
.   .   .   .   .   .   }
.   .   .   .   .   }
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
{
.   "sym": "y",
.   "lo": {
.   .   "sym": "x",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   }
.   },
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "ya"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "yb"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "yc"
.   .   .   }
.   .   }
.   },
.   "hi": {
.   .   "sym": "z",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "za"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "zb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "zc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$ print yb ya yc xb xa xc zb za zc|test-trie -u
{
.   "sym": "y",
.   "lo": {
.   .   "sym": "x",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xa"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "xb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "xc"
.   .   .   .   }
.   .   .   }
.   .   }
.   },
.   "eq": {
.   .   "sym": "b",
.   .   "lo": {
.   .   .   "sym": "a",
.   .   .   "eq": {
.   .   .   .   "val": "ya"
.   .   .   }
.   .   },
.   .   "eq": {
.   .   .   "val": "yb"
.   .   },
.   .   "hi": {
.   .   .   "sym": "c",
.   .   .   "eq": {
.   .   .   .   "val": "yc"
.   .   .   }
.   .   }
.   },
.   "hi": {
.   .   "sym": "z",
.   .   "eq": {
.   .   .   "sym": "b",
.   .   .   "lo": {
.   .   .   .   "sym": "a",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "za"
.   .   .   .   }
.   .   .   },
.   .   .   "eq": {
.   .   .   .   "val": "zb"
.   .   .   },
.   .   .   "hi": {
.   .   .   .   "sym": "c",
.   .   .   .   "eq": {
.   .   .   .   .   "val": "zc"
.   .   .   .   }
.   .   .   }
.   .   }
.   }
}
$

--[ rebalance2 ]----------------------------------------------------------------

$ json() { env LD_LIBRARY_PATH=../lib ../src/json --no-error "$@" || return 0; }
$ test-trie() { ../lib/test-trie -R|sed -nr '2{s/,?"(lo|hi)":null//g;p;q}'|json -Po; }
$ test-shuf() { diff -u100 -L "$1" <(print $1|test-trie) -L "shuffed $1" <(print $1|shuf|test-trie); }
#
# # meta command:
# $ json-trie-regtest -C rebalance|ssed -nR 's/^print\s+(.*?)\s*\|\s*test-trie\s+-u\s*$/\1/p'|while read -r a; do a="$(print $a|sort|sed -n 'H;$! b;g;s/^\n//;s/\n/ /g;p')"; echo "test-shuf \"$a\""; done
#
$ test-shuf "'' a"
$ test-shuf "a b"
$ test-shuf "a b c"
$ test-shuf "a b c d"
$ test-shuf "a b c d e"
$ test-shuf "x xa"
$ test-shuf "xa xb"
$ test-shuf "xa xb xc"
$ test-shuf "xa xb xc xd"
$ test-shuf "xa xb xc xd xe"
$ test-shuf "xy xya"
$ test-shuf "xya xyb"
$ test-shuf "xya xyb xyc"
$ test-shuf "xya xyb xyc xyd"
$ test-shuf "xya xyb xyc xyd xye"
$ test-shuf "xa xb xc ya yb yc za zb zc"
$


