# We disable autosave for technical reasons.
# Replace 0 by 120 in next line to restore default.
%autosave 0
import awalipy # If import fails, check that
# Python version used as Jupyter
# kernel matches the one
# Awalipy was compiled with.
When parsing a rational expression operator precedence is : star > concatenation > union . In other words,
a+(b*)
= a+b*
!= (a+b)*
a(b*)
= ab*
!= (ab)*
a+(bc)
= a+bc
!= (a+b)c
e = awalipy.RatExp("(a+bc)c*(ab)*")
e
By default, the alphabet of a rational expression is the set of all letters appearing in it. However the alphabet may be increased artifically as follows.
f = awalipy.RatExp("(a+b)(c*+a)*", alphabet="abcd")
f
Displaying a rational expression as a tree.
e.display()
e+f
e+=e
e
e^f
e^="abc*"
e
e.star()
e.star_here()
e
e.star_height()
e.star_normal_form()
The method expand
distribute union and concatenation as much as possible.
awalipy.RatExp("(a+bc)(d+e)(f+g)*").expand()
By default, awali uses the derived term algorithm.
A = e.exp_to_aut()
A.display()
The states of A
are indeed all the derived expressions of e
. It may be displayed by setting to True
the optional argument history
.
A.display(horizontal=False,history=True)
For convenience, one may give an expression to the constructor of an automaton.
A = awalipy.Automaton(awalipy.RatExp("01*0*"))
A.display()
Awali implements multiple algorithms for transforming expressions to automata, such as thompson or standard
g = awalipy.RatExp("1*0")
g.exp_to_aut("thompson").display()
g.exp_to_aut("standard").display()
Weights must be put between "<>" and weights takes precedence over other operators:
<-1>a*
= (<-1>a)*
!= <-1>(a*)
<-1>ab
= (<-1>a)b
!= <-1>(ab)
<-1>a+b
= (<-1>a)+b
!= <-1>(a+b)
The weighset must be given as a second argument at construction.
h = awalipy.RatExp("(<1>a*+<-1>(b*))","Z")
h
h.display()
awalipy.RatExp("<-2>","Z")
i = h ^ h + ("<-1>" ^ h).star()
i
For aut_to_exp
or standard
to work, the rational expression needs to be valid.
An expression is valid if, in every sub-expression, the weight of $\epsilon$ is well defined.
For instance the expression *(< 2 >\e)** is not valid (with weightset $(\mathbb{Z},+,\times$))
i.is_valid()
i.exp_to_aut().display()
The method thompson()
is not suitable for weighted expressions.
Indeed, let us consider the following valid expression g
:
g = awalipy.RatExp("(<1>(a*)+<-1>(b*))*","Z")
g.is_valid()
G = g.exp_to_aut(method="thompson")
G.display(horizontal=False)
In this case, thompson
produces an automaton that is not valid.
G.is_valid()
The method constant_term
gives the weight of epsilon
j = awalipy.RatExp("<3>((<1/4>(a*)+<1/4>(b*))*)<2>","Q")
j
j.constant_term()
j.get_weightset()
The method exp.get_kind()
gives the top level kind of a RatExp exp
.
(For instance, below, the top level operator of expression j
is the Kleene star.)
j.get_kind()
The method get_kind()
returns an object of RatExpKind
, which is a sort of enum. The different instances are accessible as follows.
awalipy.RatExp.ZERO
awalipy.RatExp.ONE
awalipy.RatExp.ATOM
awalipy.RatExp.SUM
awalipy.RatExp.PROD
awalipy.RatExp.STAR
The list of all possible instances of RatExpKind
can be accessed via RatExpKind.instance
.
awalipy.RatExpKind.instances
Object of type RatExpKind
can be converted to or built from their integer value or their string value as follows.
awalipy.RatExpKind.of["STAR"]
str(awalipy.RatExp.PROD)
awalipy.RatExpKind.of[2]
int(awalipy.RatExp.ATOM)
The method ratexp.children()
gives the sub-expressions of a RatExp
ratexp
.
j.children()
In the case where the expression is a RatExp.ATOM
, then children()
gives the held label as string.
k = awalipy.RatExp('a')
k.get_kind()
k.children()
l = awalipy.RatExp('<2>a','Z')
l.get_kind()
l.children()
The method ratexp.weight()
gives the left and right weights of a RatExp
ratexp
.
j.display()
j.weight()
k.display()
k.weight()
l.display()
l.weight()
The method ratexp.content()
gives the full top-level content of a RatExp
exp
.
j.display()
j
j.content()