rlsm 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +12 -4
- data/bin/smon +39 -2
- data/{lib/data → data}/monoids.db +0 -0
- data/lib/database.rb +95 -0
- data/lib/monkey_patching/array_ext.rb +50 -0
- data/lib/rlsm.rb +6 -49
- data/lib/{dfa.rb → rlsm/dfa.rb} +65 -4
- data/lib/{monoid.rb → rlsm/monoid.rb} +18 -6
- data/lib/{re.rb → rlsm/re.rb} +16 -4
- data/lib/smon/base.rb +284 -0
- data/lib/smon/db.rb +98 -0
- data/lib/smon/dot.rb +65 -0
- data/lib/smon/latex.rb +313 -0
- data/lib/smon/smon.rb +183 -0
- data/stdarb.tex +118 -0
- metadata +14 -6
data/lib/smon/smon.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rlsm'))
|
2
|
+
|
3
|
+
class SMON
|
4
|
+
def self.tmp_filename
|
5
|
+
"tmp" + Time.now.to_s.gsub(/[ :+]/, '')
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.add_help(desc)
|
9
|
+
name = desc.delete(:name).to_s
|
10
|
+
@@__help[name] = desc
|
11
|
+
end
|
12
|
+
|
13
|
+
@@__help = {}
|
14
|
+
|
15
|
+
def initialize(args = {:files => []})
|
16
|
+
puts "Welcome to SMON (v#{RLSM::VERSION})"
|
17
|
+
|
18
|
+
#Setting up internal variables
|
19
|
+
@out = args[:messenger] || STDOUT
|
20
|
+
|
21
|
+
if args[:path]
|
22
|
+
@loadpath = [File.expand_path(File.dirname(__FILE__))] +
|
23
|
+
args[:path].split(':').map { |f| File.expand_path(f) }
|
24
|
+
else
|
25
|
+
@loadpath = [File.expand_path(File.dirname(__FILE__))]
|
26
|
+
end
|
27
|
+
|
28
|
+
@objects = []
|
29
|
+
@__cmds = []
|
30
|
+
|
31
|
+
#Set up internal help system.
|
32
|
+
SMON.add_help :type => 'cmd',
|
33
|
+
:name => 'help',
|
34
|
+
:summary => 'Shows help for commands.',
|
35
|
+
:usage => 'help [<cmd>]',
|
36
|
+
:description => <<DESC
|
37
|
+
If no argument is given, displays an overview of all availible
|
38
|
+
commands.
|
39
|
+
|
40
|
+
The optional <cmd> parameter should be a String or a Symbol, if given,
|
41
|
+
displays the help to this command.
|
42
|
+
DESC
|
43
|
+
|
44
|
+
SMON.add_help :type => 'cmd',
|
45
|
+
:name => 'exit',
|
46
|
+
:summary => 'Finishes the program.',
|
47
|
+
:usage => 'exit',
|
48
|
+
:description => <<DESC
|
49
|
+
Finishes the program. Mostly useful in interactive mode.
|
50
|
+
DESC
|
51
|
+
|
52
|
+
SMON.add_help :type => 'cmd',
|
53
|
+
:name => 'libload',
|
54
|
+
:summary => 'Loads a library.',
|
55
|
+
:usage => 'libload <lib>',
|
56
|
+
:description => <<DESC
|
57
|
+
Searches in the directorys listed in the @loadpath variable for a file
|
58
|
+
called '<lib>.rb' or '<lib>' and includes it.
|
59
|
+
|
60
|
+
The file content must be a module with name 'SMONLIB<lib>'.
|
61
|
+
DESC
|
62
|
+
|
63
|
+
#Load all base libraries
|
64
|
+
['base', 'db', 'latex', 'dot'].each do |lib|
|
65
|
+
process_command "libload '#{lib}'"
|
66
|
+
end
|
67
|
+
|
68
|
+
#Select the mode
|
69
|
+
if args[:files].empty?
|
70
|
+
interactive_mode
|
71
|
+
else
|
72
|
+
args[:files].each do |file|
|
73
|
+
execute file
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def libload(lib)
|
79
|
+
load = []
|
80
|
+
@loadpath.each do |path|
|
81
|
+
load << Dir.glob( File.join(path, lib) )
|
82
|
+
load << Dir.glob( File.join(path, lib + '.rb') )
|
83
|
+
end
|
84
|
+
|
85
|
+
load.flatten!
|
86
|
+
|
87
|
+
if load.empty?
|
88
|
+
STDERR.puts "E: Could not load library '#{lib}'."
|
89
|
+
else
|
90
|
+
require load[0]
|
91
|
+
self.class.class_eval "include SMONLIB#{lib}"
|
92
|
+
STDERR.puts "I: Loaded #{lib}"
|
93
|
+
end
|
94
|
+
|
95
|
+
@__cmds = find_all_commands
|
96
|
+
end
|
97
|
+
|
98
|
+
def method_missing(cmd, *args)
|
99
|
+
puts "Error: Unknown command '#{cmd}'."
|
100
|
+
end
|
101
|
+
|
102
|
+
def help(topic = nil)
|
103
|
+
if topic
|
104
|
+
t = topic.to_s
|
105
|
+
if @@__help.key? t
|
106
|
+
@out.puts @@__help[t][:summary]
|
107
|
+
@out.puts "\nUSAGE: " + @@__help[t][:usage]
|
108
|
+
@out.puts
|
109
|
+
@out.puts @@__help[t][:description]
|
110
|
+
else
|
111
|
+
@out.puts "No help for '#{t}' availible."
|
112
|
+
end
|
113
|
+
else
|
114
|
+
@@__help.each_pair do |name, desc|
|
115
|
+
@out.puts name.to_s + "\t\t" + desc[:summary]
|
116
|
+
end
|
117
|
+
@out.puts
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
def interactive_mode
|
123
|
+
puts "Entering interactive mode."
|
124
|
+
|
125
|
+
@interactive = true
|
126
|
+
setup_readline
|
127
|
+
|
128
|
+
puts "\nInteractive mode started."
|
129
|
+
puts "Type 'help' to get an overview of all availible commands or"
|
130
|
+
puts "type 'help :help' for an explanation of the help system."
|
131
|
+
|
132
|
+
loop { process_command Readline.readline("smon:> ", true) }
|
133
|
+
end
|
134
|
+
|
135
|
+
def execute(file)
|
136
|
+
if File.exists? file
|
137
|
+
STDOUT.puts "Executing file '#{file}' ..."
|
138
|
+
begin
|
139
|
+
instance_eval File.open(file, 'r') { |f| f.read }
|
140
|
+
rescue => e
|
141
|
+
STDERR.puts "E: Error while executing '#{file}'. #{e.message}"
|
142
|
+
end
|
143
|
+
else
|
144
|
+
raise Exception, "File '#{file}' not found."
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def find_all_commands
|
149
|
+
['exit'] + self.public_methods -
|
150
|
+
(Object.public_methods + ['method_missing'])
|
151
|
+
end
|
152
|
+
|
153
|
+
def setup_readline
|
154
|
+
require 'readline'
|
155
|
+
|
156
|
+
if @__cmds.include? 'db_stat'
|
157
|
+
@__cmds += RLSM::MonoidDB::Columns.map { |x| x.inspect + " =>" }
|
158
|
+
end
|
159
|
+
|
160
|
+
Readline.completion_proc = lambda do |str|
|
161
|
+
pos = @__cmds.find_all { |cmd| cmd =~ Regexp.new("^#{str}") }
|
162
|
+
pos.size == 1 ? pos.first : nil
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def process_command(cmd)
|
167
|
+
begin
|
168
|
+
if cmd =~ Regexp.new("^(#{@__cmds.join('|')})")
|
169
|
+
instance_eval(cmd)
|
170
|
+
else
|
171
|
+
STDOUT.puts "=> " + instance_eval(cmd).inspect
|
172
|
+
end
|
173
|
+
rescue RLSMException => e
|
174
|
+
STDERR.puts "An error occured. #{e.message}"
|
175
|
+
rescue SystemExit
|
176
|
+
STDOUT.puts "Cya."
|
177
|
+
exit
|
178
|
+
rescue Exception => e
|
179
|
+
STDERR.puts "An unexpected error occured. #{e.message}"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
data/stdarb.tex
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
\documentclass[a4paper, halfparskip*]{scrartcl}
|
2
|
+
|
3
|
+
\usepackage[utf8]{inputenc}
|
4
|
+
\usepackage[T1]{fontenc}
|
5
|
+
\usepackage[german]{babel}
|
6
|
+
|
7
|
+
\usepackage{amsmath,paralist}
|
8
|
+
|
9
|
+
\begin{document}
|
10
|
+
\section{Theoretische Grundlagen}
|
11
|
+
\label{sec:tg}
|
12
|
+
In diesem Abschnitt geht es uns darum, die wichtigsten theoretischen Grundlagen
|
13
|
+
darzulegen.
|
14
|
+
|
15
|
+
\subsection{Magmen, Halbgruppen und Monoide}
|
16
|
+
\label{sec:tg:monoide}
|
17
|
+
\textbf{Defintion:} Sei $\emptyset \neq M$ eine Menge. Eine Abbildung
|
18
|
+
\begin{equation*}
|
19
|
+
* \colon M \times M \to M,\, (a,b) \mapsto a*b
|
20
|
+
\end{equation*}
|
21
|
+
heißt \emph{(binäre) Operation auf $M$}. Eine Operation heißt \emph{assoziativ}, falls
|
22
|
+
\begin{equation*}
|
23
|
+
\forall a,b,c\in M \colon a*(b*c) = (a*b)*c
|
24
|
+
\end{equation*}
|
25
|
+
und sie heißt \emph{kommutativ}, falls
|
26
|
+
\begin{equation*}
|
27
|
+
\forall a,b\in M \colon a*b = b*a
|
28
|
+
\end{equation*}
|
29
|
+
|
30
|
+
Ein \emph{Magma} $M$ ist eine nichtleere Menge zusammen mit einer Operation $*$
|
31
|
+
auf $M$. Ist die Operation assoziativ, so nennen wir $M$ eine \emph{Halbgruppe}.
|
32
|
+
|
33
|
+
\textit{Bemerkung:} Sofern keine Verwirrung entstehen kann, werden wir die
|
34
|
+
Operation nicht explizit mitangeben und schreiben statt $a*b$ einfach
|
35
|
+
$ab$. Zusätzlich definieren wir für natürliche Zahlen $n\geq 1$ und ein Element
|
36
|
+
$a\in M$ rekursiv
|
37
|
+
\begin{equation*}
|
38
|
+
a^1 := a;\quad a^n := a*a^{n-1}
|
39
|
+
\end{equation*}
|
40
|
+
|
41
|
+
|
42
|
+
\textbf{Defintion:} Sei $M$ ein Magma und $x\in M$. Dann heißt $x$
|
43
|
+
\begin{enumerate}[(a)]
|
44
|
+
\item \emph{Neutralelement}, falls $\forall a\in M\colon xa = ax = a$.
|
45
|
+
\item \emph{Links-Nullelement}, falls $\forall a\in M\colon xa = x$.
|
46
|
+
\item \emph{Rechts-Nullelement}, falls $\forall a\in M\colon ax = x$.
|
47
|
+
\item \emph{Nullelement}, falls es ein Links- und Rechts-Nullelement ist.
|
48
|
+
\item \emph{idempotent}, falls $x^2 = x$. Sind alle Elemente eines Magmas
|
49
|
+
idempotent, so nennen wir das Magma selbst \emph{idempotent}.
|
50
|
+
\item \emph{Inverses zu $a$}, falls $ax = xa = 1$, wobei $1$ ein Neutralelement
|
51
|
+
bezeichnet.
|
52
|
+
\end{enumerate}
|
53
|
+
Ein \emph{Monoid} ist eine Halbgruppe mit einem Neutralelement. Ein Monoid in
|
54
|
+
dem jedes Element ein Inverses besitzt heißt \emph{Gruppe}.
|
55
|
+
|
56
|
+
\textit{Bemerkung:} Falls ein Inverses, Neutral- oder Nullelement existiert,
|
57
|
+
so ist es eindeutig. Der Beweis dafür ist leicht und in jedem Lehrbuch zur
|
58
|
+
Algebra zu finden. Wir werden in Zukunft immer das Symbol $1$ für das
|
59
|
+
Neutralelement eines Monoids $M$ verwenden (oder auch $1_M$ um deutlich zu
|
60
|
+
machen, dass dies das Neutralelement von $M$ ist) und das Symbol $0$ bezeichnet
|
61
|
+
immer das Nullelement, falls es existiert. Das Inverse zu $a$ bezeichnen wir mit
|
62
|
+
$a^{-1}$ (falls es existiert).
|
63
|
+
|
64
|
+
Im Fall eines Monoids $M$ setzen wir noch $a^0 = 1$ für jedes $a\in M$.
|
65
|
+
|
66
|
+
\textbf{Definition:} Sei $M$ ein Monoid. Eine Menge $N$ heißt
|
67
|
+
\emph{Untermonoid} von $M$, in Zeichen $N\leq M$, falls
|
68
|
+
\begin{enumerate}[(i)]
|
69
|
+
\item $N \subseteq M$
|
70
|
+
\item $1_N = 1_M$
|
71
|
+
\item $\forall a,b\in N \colon a*b\in N$
|
72
|
+
\end{enumerate}
|
73
|
+
|
74
|
+
\textit{Bemerkung:} $N$ wird mit der Operation $\circ = *|_{N\times N}$ selbst
|
75
|
+
zu einem Monoid.
|
76
|
+
|
77
|
+
\textbf{Proposition:} Der Schnitt von Untermonoiden ist wieder ein Untermonoid.
|
78
|
+
|
79
|
+
\textbf{Definition:} Sei $M$ ein Monoid und $N \subset M$. Der von $N$
|
80
|
+
\emph{erzeugte Untermonoid} ist
|
81
|
+
\begin{equation*}
|
82
|
+
\langle N \rangle := \bigcap_{N \subset S \leq M} S
|
83
|
+
\end{equation*}
|
84
|
+
|
85
|
+
Eine Menge $E$ heißt \emph{Erzeuger} von $M$, falls $\langle E \rangle = M$.
|
86
|
+
|
87
|
+
\textbf{Defintion:} Seien $(M,*)$ und $(N,\circ)$ Monoide. Eine Abbildung $\phi\colon M \to
|
88
|
+
N$ heißt \emph{(Monoid-)Homomorphismus}, falls
|
89
|
+
\begin{enumerate}[(i)]
|
90
|
+
\item $\phi(1_M) = 1_N$
|
91
|
+
\item $\forall a,b \in M \colon \phi(a*b) = \phi(a)\circ\phi(b)$
|
92
|
+
\end{enumerate}
|
93
|
+
Ein Homomorphismus $\phi$ heißt
|
94
|
+
\begin{enumerate}[(a)]
|
95
|
+
\item \emph{Monomorphismus}, falls $\phi$ injektiv ist.
|
96
|
+
\item \emph{Epimorphismus}, falls $\phi$ surjektiv ist.
|
97
|
+
\item \emph{Isomorphismus}, falls $\phi$ bijektiv ist.
|
98
|
+
\end{enumerate}
|
99
|
+
|
100
|
+
|
101
|
+
\subsection{Formale Sprachen}
|
102
|
+
\label{sec:tg:fs}
|
103
|
+
|
104
|
+
\textbf{Defintion:} Wir nennen eine endliche nichleere Menge $\Sigma$ ein
|
105
|
+
\emph{Alphabet} und Elemente von $\Sigma$ Buchstaben. Der freie Monoid über
|
106
|
+
$\Sigma$ bezeichnen wir mit $\Sigma^*$ und das Neutralelement darin bezeichnen
|
107
|
+
wir mit $\lambda$
|
108
|
+
|
109
|
+
|
110
|
+
\subsection{Deterministische endliche Automaten}
|
111
|
+
\label{sec:tg:dfa}
|
112
|
+
|
113
|
+
% \textbf{Proposition:} Sei $M$ eine Halbgruppe und $x\in M$. Dann gibt es eine
|
114
|
+
% natürliche Zahl $n\geq 1$, sodass $x^n$ idempotent ist.
|
115
|
+
|
116
|
+
% \textbf{Korollar:} Ein Monoid ist genau dann eine Gruppe, wenn das einzige
|
117
|
+
% idempotente Element das Neutralelement ist.
|
118
|
+
\end{document}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rlsm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- asmodis
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-03-10 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -39,11 +39,19 @@ files:
|
|
39
39
|
- README.txt
|
40
40
|
- Rakefile
|
41
41
|
- bin/smon
|
42
|
-
-
|
43
|
-
- lib/
|
44
|
-
- lib/
|
45
|
-
- lib/re.rb
|
42
|
+
- data/monoids.db
|
43
|
+
- lib/database.rb
|
44
|
+
- lib/monkey_patching/array_ext.rb
|
46
45
|
- lib/rlsm.rb
|
46
|
+
- lib/rlsm/dfa.rb
|
47
|
+
- lib/rlsm/monoid.rb
|
48
|
+
- lib/rlsm/re.rb
|
49
|
+
- lib/smon/base.rb
|
50
|
+
- lib/smon/db.rb
|
51
|
+
- lib/smon/dot.rb
|
52
|
+
- lib/smon/latex.rb
|
53
|
+
- lib/smon/smon.rb
|
54
|
+
- stdarb.tex
|
47
55
|
has_rdoc: true
|
48
56
|
homepage: http://www.github.com/asmodis/rlsm
|
49
57
|
post_install_message:
|