예제 #1
0
def check_algo(i, o, algo):
    i = vcsn.automaton(i)
    o = vcsn.automaton(o)

    print("using algorithm: ", algo)
    print("checking proper")

    # We call sort().strip() everywhere to avoid seeing differences
    # caused by the different numbering of the states between the
    # algorithms.
    CHECK_EQ(o.sort().strip(), i.proper(algo=algo).sort().strip())

    # Since we remove only states that _become_ inaccessible,
    # i.proper(prune=False).accessible() is not the same as i.proper():
    # in the former case we also removed the non-accessible states.
    print("checking proper(prune=False)")
    CHECK_EQ(o.accessible(), i.proper(prune=False, algo=algo).accessible())

    # FIXME: Because proper uses copy, state numbers are changed.
    #
    # FIXME: cannot use is_isomorphic because some of our test cases
    # have unreachable states, which is considered invalid by
    # is_isomorphic.
    print("checking idempotence")
    p = i.proper(algo=algo)
    if p.is_accessible():
        CHECK_ISOMORPHIC(p, p.proper(algo=algo))
    else:
        CHECK_EQ(p.sort().strip(), p.proper(algo=algo).sort().strip())
예제 #2
0
def check(input, exp):
    if isinstance(input, str):
        input = vcsn.automaton(input)
    if isinstance(exp, str):
        exp = vcsn.automaton(exp)
    CHECK_EQ(exp, input.star())
    check_algo(input)
예제 #3
0
def check(i, exp=None):
  if not exp:
    exp = i
  i = vcsn.automaton(i)
  CHECK_EQ(exp, i.insplit())
  # Idempotence.
  CHECK_ISOMORPHIC(vcsn.automaton(exp), i.insplit().insplit())
예제 #4
0
def check(i, o):
    if isinstance(i, str):
        i = vcsn.automaton(i)
    CHECK(not i.is_complete())
    o = vcsn.automaton(o)
    CHECK(o.is_complete())
    CHECK_EQ(o, i.complete())
    # Idempotence.
    CHECK_EQ(o, o.complete())
예제 #5
0
def check(input, exp):
  if isinstance(input, str):
    input = vcsn.automaton(input)
  CHECK(not input.is_out_sorted())
  aut = input.sort()
  CHECK_EQ(exp, aut)
  CHECK(aut.is_out_sorted())
예제 #6
0
def check_fail_algo(aut, algo):
    a = vcsn.automaton(aut)
    try:
        a.proper(algo=algo)
        FAIL(r"invalid \\e-cycle not detected")
    except RuntimeError:
        PASS()
예제 #7
0
def null_state(weightset, weight):
    return vcsn.automaton('''
context = "lal_char, {ws}"
$ -> 0
0 -> 1 a
0 -> 2 <{w}>a
1 -> 3 b
2 -> 3 b'''.format(w=weight, ws=weightset))
예제 #8
0
def check_trim(input, exp):
    if isinstance(input, str):
        input = vcsn.automaton(input)
    aut = input.trim()
    CHECK_EQ(exp, aut)
    CHECK(aut.is_trim())
    CHECK(aut.is_accessible())
    CHECK(aut.is_coaccessible())

    CHECK_EQ(exp, input.coaccessible().accessible())
    CHECK_EQ(exp, input.accessible().coaccessible())
예제 #9
0
def null_state_det(weightset, weight):
    return vcsn.automaton('''
digraph
{{
  vcsn_context = "letterset<char_letters(ab)>, {ws}"
  rankdir = LR
  edge [arrowhead = vee, arrowsize = .6]
  {{
    node [shape = point, width = 0]
    I0
  }}
  I0 -> 0 [color = DimGray]
  0 -> 1 [label = "a", color = DimGray]
}}'''.format(ws=ws, w=w))
예제 #10
0
 def update(self, *_):
     self.updater.abort()
     self.err.value = ''
     self.out.clear_output()
     try:
         txt = self.text.value
         a = vcsn.automaton(txt, self.format, strip=False)
         self.ipython.shell.user_ns[self.name] = \
             a.strip() if self.strip else a
         # There is currently no official documentation on this,
         # so please check out `ipywidgets.Output`'s docstring.
         with self.out:
             a._display(self.mode.value, self.engine.value)
     except RuntimeError as e:
         self.err.value = formatError(e)
예제 #11
0
def check(algo, aut, exp):
    if isinstance(algo, list):
        for a in algo:
            check(a, aut, exp)
    else:
        print('checking minimize with algorithm ', algo)
        CHECK_EQ(exp, aut.minimize(algo))
        # Check that repeated minimization still gives the same type of
        # automaton.  We don't want to get partition_automaton of
        # partition_automaton: one "layer" suffices.
        CHECK_EQ(exp, aut.minimize(algo).minimize(algo))

        # Cominimize.
        #
        # Do not work just on the transpose_automaton, to make sure it
        # works as expected for "forward" automata (which did have one
        # such bug!).  So copy the transposed automaton.
        t = aut.transpose().automaton(aut.context())
        if isinstance(exp, str):
            exp = vcsn.automaton(exp)
        CHECK_ISOMORPHIC(exp.transpose(), t.cominimize(algo))
예제 #12
0
def check(aut, fefsm):
    'Check the conversion to and from FSM.'
    print(here() + ": check:", fefsm)

    # The reference: text in efsm format.
    efsm = open(medir + "/" + fefsm).read().strip()

    # Check output to EFSM.
    CHECK_EQ(efsm, aut.format('efsm'))

    # Check print | read | print to EFSM.
    #
    # We used to check that the output is exactly what we get when
    # reading back and printing again.  This does not work for automata
    # with several initial states or a non-one initial weight (which is
    # approximated below as !is_standard), as then we show pre as the
    # real initial state.  The pre state is displayed as the state
    # number immediately after the highest state number, and when read
    # and printed back by OpenFST, it is renumbered as 0.
    #
    # So (read | print) is not the identity.
    aut2 = vcsn.automaton(efsm, 'efsm')
    if aut.is_standard():
        print(here(), 'case standard')
        CHECK_EQ(aut, aut2)
        CHECK_EQ(efsm, aut2.format('efsm'))
    else:
        print(here(), 'case non standard')
        CHECK_EQUIV(aut, normalize(aut2))

    # Check that OpenFST accepts and reproduces our EFSM files.
    if have_ofst:
        if aut.is_standard():
            print(here(), 'fstcat: eq')
            CHECK_EQ(aut, aut.fstcat())
        else:
            print(here(), 'fstcat: equiv')
            CHECK_EQUIV(aut, normalize(aut.fstcat()))
    else:
        SKIP('OpenFST is missing')
예제 #13
0
    def _aut_of_d3(self):
        '''Conversion from d3 to an automaton, via "daut".'''
        self.error.value = ''
        ctx = 'context = {:s}\n'.format(self.context)
        trans = self._widget.transitions
        aut = ''
        def get_state(obj):
            '''Convert whatever the given state is into a daut state.'''
            # Things that are not constant:
            #  - PRE and POST are decimals or '$'
            #  - states are strings or dicts
            if isinstance(obj, dict):
                state = str(obj['id'])
            elif isinstance(obj, str):
                state = obj
            try:
                # State ID is a valid integer number
                int(state)
                return state
            except ValueError:
                return '$'

        for t in trans:
            src = get_state(t['source'])
            dst = get_state(t['target'])
            aut += "{} -> {} {}\n".format(src, dst, t['label'])
        res = ctx + aut
        try:
            self.error.value = str(trans)
            return vcsn.automaton(res, 'daut')
        except RuntimeError as e:
            ts = ['{} -> {}'.format(t['source']['id'], t['target']['id'])
                  for t in trans
                  if isinstance(t['source'], dict) and isinstance(t['target'], dict)]
            self.error.value = vcsn.ipython.formatError(str(e)
                                                        + '\n#####\n'
                                                        + res
                                                        + '\n#####\n'
                                                        + '\n'.join(ts))
예제 #14
0
 def automaton(self, line, cell=None):
     '''An automaton editor.'''
     args = parse_argstring(self.automaton, line)
     if not args.var.isidentifier():
         raise NameError('`{}` is not a valid variable name'.format(
             args.var))
     if cell is None:
         # Line magic.
         if args.format == 'auto':
             args.format = 'daut'
         if args.format == 'gui':
             a = d3Widget.VcsnD3DataFrame(self, args.var)
             a.show()
         else:
             AutomatonText(self,
                           args.var,
                           args.format,
                           layout=args.layout,
                           strip=args.strip)
     else:
         # Cell magic.
         a = vcsn.automaton(cell, format=args.format, strip=args.strip)
         self.shell.user_ns[args.var] = a
         display(a)
예제 #15
0
파일: compare.py 프로젝트: pombredanne/vcsn
## ---------- ##


# We do not bind the compare functions, which are too precise
# currently: swapping two transitions make the automata different.
def check_lt(a1, a2):
    CHECK_EQ(True, a1.compare(a2) < 0)
    CHECK_EQ(True, a2.compare(a1) > 0)
    CHECK_EQ(0, a1.compare(a1))
    CHECK_EQ(0, a2.compare(a2))


ctx = vcsn.context('lal_char, q')
# First, comparison on source state numbers.
a1 = vcsn.automaton('''context = lal, z
0 -> 0 a
0 -> 1 a
''')
a2 = vcsn.automaton('''context = lal, z
0 -> 0 a
1 -> 0 a
''')
check_lt(a1, a2)

# Second, comparison on labels.
a1 = vcsn.automaton('''context = lal, z
$ -> 0
0 -> 0 a
0 -> $''')
a2 = vcsn.automaton('''context = lal, z
$ -> 0
0 -> 0 b
예제 #16
0
def datafile(f):
    return '{datadir}/sms2fr/{file}.efsm'.format(
        datadir=vcsn.config('configuration.datadir'), file=f)


# Handle arguments.
def create_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-s',
                        '--syntactic',
                        type=str,
                        default=datafile('syntactic'))
    parser.add_argument('-g',
                        '--graphemic',
                        type=str,
                        default=datafile('graphemic'))
    return parser.parse_args()


args = create_args()

# Read the graphemic automaton.
grap = vcsn.automaton(filename=args.graphemic)
# Read the syntactic automaton.
synt = vcsn.automaton(filename=args.syntactic).partial_identity()

for line in sys.stdin:
    trad = sms_to_fr(line.replace('\n', ''), grap, synt)
    eff = re.match('<(.*)>(.*)', trad).group(2)
    print(eff[3:-3].replace('#', ' '))
예제 #17
0
def meaut(fn, ext=None):
    '''The automaton stored in the test's file `fn.ext`,
    where `ext` is possibly empty.'''
    return vcsn.automaton(filename=mefile(fn, ext))
예제 #18
0
def xfail(algo, aut):
    res = ''
    try:
        res = aut.minimize(algo)
    except RuntimeError:
        PASS()
    else:
        FAIL('did not raise an exception', str(res))


## Simple minimization test.  The example comes from the "Théorie des
## langages" lecture notes by François Yvon & Akim Demaille.
## Automaton 4.23 at page 59, as of revision a0761d6.
a = meaut('redundant.gv')
exp = metext('redundant.exp.gv')
check('brzozowski', a, vcsn.automaton(exp))
check(algos, a, exp)

## An automaton equal to redundant.exp, with one transition removed.
a = meaut('incomplete-non-trim.gv')
#xfail('brzozowski', a)
xfail('moore', a)
xfail('signature', a)
xfail('weighted', a)

## An automaton equal to redundant.exp, with no initial states.  It
## must be minimized into an empty automaton.
a = meaut('no-initial-states.gv')
z = metext('no-initial-states.exp.gv')
check('brzozowski', a, z)
xfail('moore', a)
예제 #19
0
import vcsn
from test import *

def check(i, o):
  i1 = i.push_weights()
  CHECK_EQ(o, i1)
  # Make sure the expected result is consistant.
  CHECK_EQUIV(o, i1)

# q
i = vcsn.automaton('''digraph {
  vcsn_context = "lal_char(abc), q"
  I0 -> 0
  0 -> 1 [label = "<2>a"]
  1 -> 2 [label = "<3>b"]
  2 -> 3 [label = "<5>c"]
  3 -> 4 [label = "<2>b"]
  1 -> 3 [label = "<8>c"]
  4 -> F4
}''')
o = vcsn.automaton('''digraph {
  vcsn_context = "lal_char(abc), q"
  I0 -> 0 [label = "<92>"]
  0 -> 1 [label = "a"]
  1 -> 2 [label = "<15/23>b"]
  1 -> 3 [label = "<8/23>c"]
  2 -> 3 [label = "c"]
  3 -> 4 [label = "b"]
  4 -> F4
}''')
check(i, o)
예제 #20
0
    p = aut.proper().sort().strip()
    CHECK_EQUIV(p, pfst)


if have_ofst:
    # Conjunction: check that OpenFST and Vcsn understand the weights
    # the same way.  We have zmin and log in common.
    for f in [
            vcsn.datadir + '/lal_char_zmin/minblocka.gv',
            vcsn.datadir + '/lal_char_zmin/slowgrow.gv',
            medir + '/lal-char-log.gv'
    ]:
        print("Conjunction:", f)
        #
        # a & 2 by Vcsn.
        a = vcsn.automaton(filename=f)
        a2_vcsn = a & 2

        # c1 & c1 by OpenFST.
        a2_ofst = a.fstconjunction(a)

        CHECK_EQ(a2_vcsn, a2_ofst)

    # Make sure determinizations agree.  This automaton, determinized,
    # has weights on the final states only, which exercises a bug we
    # once had.
    print("Determinize")
    zmin = vcsn.context('lal_char(ab), zmin')
    a = zmin.expression('[ab]*a(<2>[ab])').automaton()
    d_vcsn = a.determinize().strip()
    d_ofst = a.fstdeterminize()
예제 #21
0
#! /usr/bin/env python

import vcsn
from test import *

## ----- ##
## LAL.  ##
## ----- ##

a = vcsn.automaton('''digraph {
  vcsn_context = "lat<lal_char(abc), lal_char(xyz)>, z"
  I0 -> 0
  0 -> 1 [label = "<2>(a, x)"]
  1 -> 2 [label = "<3>(b, y)"]
  2 -> F2
}''')
CHECK(a.is_functional())

a = vcsn.automaton(r'''digraph {
  vcsn_context = "lat<lal_char(abc),lal_char(xyz)>, b"
  I0 -> 0
  0 -> 1 [label = "(a, x)"]
  0 -> 2 [label = "(a, x)"]
  1 -> 3 [label = "(b, y)"]
  2 -> 3 [label = "(b, y)"]
  3 -> F3
}''')
CHECK(a.is_functional())

a = vcsn.automaton('''digraph {
  vcsn_context = "lat<lal_char(abc),lal_char(xyz)>, b"
예제 #22
0
#! /usr/bin/env python

import vcsn
from test import *

# Not deterministic, yet not ambiguous.
a = vcsn.automaton('''
digraph
{
  vcsn_context="lal_char(ab), b"
  I -> 0
  0 -> 1 [label = "a"]
  0 -> 2 [label = "a"]
  1 -> F
}
''')
CHECK(not a.is_ambiguous())
XFAIL(lambda: a.ambiguous_word(), "automaton is unambiguous")
CHECK(not a.is_deterministic())

# Not deterministic, and ambiguous.
a = vcsn.automaton('''
digraph
{
  vcsn_context="lal_char(ab), b"
  I -> 0
  0 -> 1 [label = "a"]
  0 -> 2 [label = "a"]
  1 -> F
  2 -> F
}
예제 #23
0
#! /usr/bin/env python

import vcsn
from test import *

## ----- ##
## LAL.  ##
## ----- ##

a = vcsn.automaton('''digraph {
  vcsn_context = "lat<lal_char(abc), lal_char>, z"
  I0 -> 0
  0 -> 1 [label = "(a, a)"]
  1 -> 2 [label = "(b, b)"]
  2 -> F2
}''')
CHECK(a.is_partial_identity())

a = vcsn.automaton('''digraph {
  vcsn_context = "lat<lal_char(abc), lal_char>, z"
  I0 -> 0
  0 -> 1 [label = "(a, a)"]
  1 -> 2 [label = "(b, c)"]
  2 -> F2
}''')
CHECK(not a.is_partial_identity())

## ----- ##
## LAW.  ##
## ----- ##
예제 #24
0
# LAN x LAN
ctx = vcsn.context('lat<lan_char(a), lan_char(x)>, q')
check_shortest(
    r'(\e|x + a|\e)*', 9,
    r'\e|\e + \e|x + a|\e + <2>a|x + \e|xx + <3>a|xx + aa|\e + <3>aa|x + <6>aa|xx'
)
check_enumerate(
    r'(\e|x + a|\e)*', 2,
    r'\e|\e + \e|x + a|\e + <2>a|x + \e|xx + <3>a|xx + aa|\e + <3>aa|x + <6>aa|xx'
)

aut = vcsn.automaton('''
context = "letterset<char_letters(a)>, q"
$ -> 0
0 -> 1 <2>a
0 -> 2 <-1>a
0 -> 3 <-1>a
1 -> $
2 -> $
3 -> $
''')
check_one(aut, 1, '\z')

aut = vcsn.automaton('''
context = "letterset<char_letters(ab)>, q"
$ -> 0
0 -> 1 <2>a
0 -> 2 <-1>a
0 -> 3 <-1>a
0 -> 4 b
1 -> $
2 -> $
예제 #25
0
result = vcsn.automaton('''
digraph
{
  vcsn_context = "lal_char(abc), b"
  rankdir = LR
  {
    node [shape = point, width = 0]
    I0
    F0
    F1
    F2
    F3
    F4
  }
  {
    node [shape = circle]
    0
    1
    2
    3
    4
  }
  I0 -> 0
  0 -> F0
  0 -> 1 [label = "a"]
  0 -> 2 [label = "b"]
  0 -> 3 [label = "b"]
  0 -> 4 [label = "c"]
  1 -> F1
  1 -> 1 [label = "a"]
  1 -> 2 [label = "b"]
  1 -> 3 [label = "b"]
  1 -> 4 [label = "c"]
  2 -> F2
  2 -> 1 [label = "a"]
  2 -> 2 [label = "b"]
  2 -> 3 [label = "b"]
  2 -> 4 [label = "c"]
  3 -> F3
  3 -> 3 [label = "b"]
  3 -> 4 [label = "c"]
  4 -> F4
  4 -> 3 [label = "b"]
  4 -> 4 [label = "c"]
}
''')
예제 #26
0
def check(exp, aut):
  CHECK_EQ(exp, vcsn.automaton(aut).is_proper())
예제 #27
0
CHECK_EQ(meaut('binary^0.gv'), binary & 0)

# power 1.
CHECK_EQ(meaut('binary^1.gv'), binary & 1)

# power 4.
binary4 = binary & 4
# 0^4 = 0.
CHECK_EQ(z.weight('0'), binary4('0'))
# 1^4 = 1.
CHECK_EQ(z.weight('1'), binary4('1'))
# 4^4 = 256.
CHECK_EQ(z.weight('256'), binary4('100'))

# Power 5.
binary5 = binary & 5
CHECK_EQ(z.weight('32'), binary5('10'))
#run 0 '' -vcsn power -o binary^5.gv -f $binary_gv 5
#run 0 32 -vcsn evaluate -f binary^5.gv 10

# Power 7.
binary7 = binary & 7
CHECK_EQ(z.weight('128'), binary7('10'))

# Check that only the accessible part is kept using binary.gv,
# modified with an inaccessible part.
inacc = binary + vcsn.automaton('''context = lal, z
0 -> 1 0''')
for i in [0, 1, 4, 7]:
    CHECK_EQ(binary & i, (inacc & i).__value__())
예제 #28
0
  I0 -> 0
  0 -> F0 [label = "<22>"]
  0 -> 0 [label = "<10>a|x, <5>b|y"]
}''')

## ------------------------------- ##
## Tools Sec. 3.3.1, Fig. 3.14.  ##
## ------------------------------- ##

a = vcsn.automaton('''
digraph {
    vcsn_context = "lal_char(abc), z"
    I -> 0
    1 -> F
    0 -> 0 [label = "a, b"]
    0 -> 1 [label = "b"]
    0 -> 2 [label = "<2>b"]
    2 -> 2 [label = "<2>a, <2>b"]
    2 -> 1 [label = "<2>b"]
    1 -> 1 [label = "<4>a, <4>b"]
}
''')
check_reduce(
    a, '''digraph
{
  vcsn_context = "letterset<char_letters(abc)>, z"
  rankdir = LR
  edge [arrowhead = vee, arrowsize = .6]
  {
    node [shape = point, width = 0]
    I0
예제 #29
0
#! /usr/bin/env python

import vcsn
from test import *

#
# Simple test, one spontaneous transition
#      a    \e   a
# -> 0 -> 1 -> 2 -> 3 ->
#

aut = vcsn.automaton(r'''
context = "lan_char(a), b"
$ -> 0
0 -> 1 a
1 -> 2 \e
2 -> 3 a
3 -> $
''')

lazy = aut.proper(lazy=True)
CHECK_EQ(
    '''digraph
{
  vcsn_context = "letterset<char_letters(a)>, b"
  rankdir = LR
  edge [arrowhead = vee, arrowsize = .6]
  {
    node [shape = point, width = 0]
    I0
    F3
예제 #30
0
# ------------------
# Check that is-normalized(INPUT) = EXPECT.
def check(expect, i):
    CHECK_EQ(expect, i.is_normalized())
    # Check normalize
    CHECK_EQ(i.standard().costandard(), i.normalize())


# A simple, normalized, non-Thompson, automaton.
check(
    True,
    vcsn.automaton('''
digraph
{
  vcsn_context = "lal_char(ab), z"
  I0 -> 0
  0 -> 1 [label = "a,b"]
  1 -> F1
}
'''))

# No initials
check(
    False,
    vcsn.automaton('''
digraph
{
  vcsn_context = "lal_char(ab), z"
  0 -> 1 [label = "a,b"]
  1 -> F
}