Execute a Markov algorithm: Difference between revisions
Content added Content deleted
(Updated Julia code) |
|||
Line 2,118: | Line 2,118: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{works with|Julia|0.6}} |
|||
""" |
|||
'''Module''': |
|||
This program expects a source rules file and a text file for translating to be provided as the |
|||
<lang julia>module MarkovAlgos |
|||
first and second arguments of the script, as in: > julia markovrules.jl <rulesfilename> <textfilename> |
|||
To run the program, make individual files containing the rulesets and test texts (see below). |
|||
struct MarkovRule{F,T} |
|||
""" |
|||
patt::F |
|||
function getmarkovrules(filename) |
|||
repl::T |
|||
term::Bool |
|||
end |
|||
linenum = 0 |
|||
open(filename) do rulesfh |
|||
isterminating(r::MarkovRule) = r.term |
|||
lines = readlines(rulesfh) |
|||
Base.show(io::IO, rule::MarkovRule) = |
|||
print(io, rule.patt, " → ", isterminating(rule) ? "." : "", rule.repl) |
|||
function Base.convert(::Type{MarkovRule}, s::AbstractString) |
|||
rmatch = match(r"^(.+)\s+->\s*(\.)?(.*)?$", s) |
|||
if rmatch ≡ nothing || isempty(rmatch.captures) |
|||
throw(ParseError("not valid rule: " * s)) |
|||
end |
end |
||
patt, term, repl = rmatch.captures |
|||
for line in lines |
|||
return MarkovRule(patt, repl ≢ nothing ? repl : "", term ≢ nothing) |
|||
linenum += 1 |
|||
end |
|||
if(!ismatch(r"^#", line) && !ismatch(r"^\s*$", line)) |
|||
regm = match(r"^(.+)\s+->\s+(\.)?(.+)?$", line) |
|||
function ruleset(file::Union{AbstractString,IO}) |
|||
if(regm != nothing && length(regm.captures) > 0) |
|||
ruleset = Vector{MarkovRule}(0) |
|||
push!(rules, (regm.captures[1], regm.captures[2], regm.captures[3])) |
|||
for line in eachline(file) |
|||
ismatch(r"(^#|^\s*$)", line) || push!(ruleset, MarkovRule(line)) |
|||
println("RULESET ERROR: No proper matches for line $linenum in file $filename.") |
|||
end |
|||
end |
|||
end |
end |
||
return ruleset |
|||
end |
end |
||
apply(text::AbstractString, rule::MarkovRule) = replace(text, rule.patt, rule.repl) |
|||
function markovtranslate(filename, rules) |
|||
function apply(file::Union{AbstractString,IO}, ruleset::AbstractVector{<:MarkovRule}) |
|||
testfh = open(filename) |
|||
text = readstring(file) |
|||
txt = join(map(c -> Char(c), read(testfh))) |
|||
redo = !isempty(text) |
|||
while redo |
|||
matchrule = false |
|||
while redoing |
|||
for rule in ruleset |
|||
if contains(text, rule.patt) |
|||
matchrule = true |
|||
text = apply(text, rule) |
|||
redo = !isterminating(rule) |
|||
if(to == nothing) |
|||
to = "" |
|||
end |
|||
txt = replace(txt, from, to) |
|||
if(terminating != nothing) |
|||
redoing = false |
|||
end |
|||
break |
break |
||
end |
end |
||
end |
end |
||
redo = redo && matchrule |
|||
redoing = false |
|||
end |
|||
end |
end |
||
return text |
|||
end |
end |
||
end # module MarkovAlgos</lang> |
|||
const rulesfile = ARGS[1] |
|||
const textfile = ARGS[2] |
|||
print("\nUsing rules from file $rulesfile, processing text $textfile.\nResult of test: ") |
|||
markovrules = getmarkovrules(rulesfile) |
|||
println(markovtranslate(textfile, markovrules)) |
|||
</lang> |
|||
<pre> |
|||
The following are the files used: |
|||
'''Main''': |
|||
<lang julia>include("module.jl") |
|||
let rulesets = @.("data/markovrules0" * string(1:5) * ".txt"), |
|||
In ruleset1.txt: |
|||
ruletest = @.("data/markovtest0" * string(1:5) * ".txt") |
|||
# This rules file is extracted from Wikipedia: |
|||
for i in eachindex(rulesets, ruletest) |
|||
# http://en.wikipedia.org/wiki/Markov_Algorithm |
|||
rules = MarkovAlgos.ruleset(rulesets[i]) |
|||
A -> apple |
|||
println("# Example n.$i") |
|||
B -> bag |
|||
println("Original:\n", readstring(ruletest[i])) |
|||
S -> shop |
|||
println("Transformed:\n", MarkovAlgos.apply(ruletest[i], rules)) |
|||
T -> the |
|||
end |
|||
the shop -> my brother |
|||
end</lang> |
|||
a never used -> .terminating rule |
|||
{{out}} |
|||
In test1.txt: |
|||
<pre># Example n.1 |
|||
Original: |
|||
I bought a B of As from T S. |
I bought a B of As from T S. |
||
Transformed: |
|||
In ruleset2.txt: |
|||
I bought a bag of apples from my brother. |
|||
# Slightly modified from the rules on Wikipedia |
|||
A -> apple |
|||
B -> bag |
|||
S -> .shop |
|||
T -> the |
|||
the shop -> my brother |
|||
a never used -> .terminating rule |
|||
# Example n.2 |
|||
In test2.txt: |
|||
Original: |
|||
I bought a B of As from T S. |
I bought a B of As from T S. |
||
Transformed: |
|||
In ruleset3.txt: |
|||
I bought a bag of apples from T shop. |
|||
# BNF Syntax testing rules |
|||
A -> apple |
|||
WWWW -> with |
|||
Bgage -> ->.* |
|||
B -> bag |
|||
->.* -> money |
|||
W -> WW |
|||
S -> .shop |
|||
T -> the |
|||
the shop -> my brother |
|||
a never used -> .terminating rule |
|||
# Example n.3 |
|||
In test3.txt: |
|||
Original: |
|||
I bought a B of As W my Bgage from T S. |
I bought a B of As W my Bgage from T S. |
||
Transformed: |
|||
In ruleset4.txt: |
|||
I bought a bag of apples with my baggage from T shop. |
|||
### Unary Multiplication Engine, for testing Markov Algorithm implementations |
|||
### By Donal Fellows. |
|||
# Unary addition engine |
|||
_+1 -> _1+ |
|||
1+1 -> 11+ |
|||
# Pass for converting from the splitting of multiplication into ordinary |
|||
# addition |
|||
1! -> !1 |
|||
,! -> !+ |
|||
_! -> _ |
|||
# Unary multiplication by duplicating left side, right side times |
|||
1*1 -> x,@y |
|||
1x -> xX |
|||
X, -> 1,1 |
|||
X1 -> 1X |
|||
_x -> _X |
|||
,x -> ,X |
|||
y1 -> 1y |
|||
y_ -> _ |
|||
# Next phase of applying |
|||
1@1 -> x,@y |
|||
1@_ -> @_ |
|||
,@_ -> !_ |
|||
++ -> + |
|||
# Termination cleanup for addition |
|||
_1 -> 1 |
|||
1+_ -> 1 |
|||
_+_ -> |
|||
# Example n.4 |
|||
In test4.txt: |
|||
Original: |
|||
_1111*11111_ |
_1111*11111_ |
||
Transformed: |
|||
In ruleset5.txt: |
|||
11111111111111111111 |
|||
# Turing machine: three-state busy beaver |
|||
# |
|||
# state A, symbol 0 => write 1, move right, new state B |
|||
A0 -> 1B |
|||
# state A, symbol 1 => write 1, move left, new state C |
|||
0A1 -> C01 |
|||
1A1 -> C11 |
|||
# state B, symbol 0 => write 1, move left, new state A |
|||
0B0 -> A01 |
|||
1B0 -> A11 |
|||
# state B, symbol 1 => write 1, move right, new state B |
|||
B1 -> 1B |
|||
# state C, symbol 0 => write 1, move left, new state B |
|||
0C0 -> B01 |
|||
1C0 -> B11 |
|||
# state C, symbol 1 => write 1, move left, halt |
|||
0C1 -> H01 |
|||
1C1 -> H11 |
|||
# Example n.5 |
|||
In test5.txt: |
|||
Original: |
|||
000000A000000 |
000000A000000 |
||
</pre> |
|||
{{output}} |
|||
<pre> |
|||
prompt>julia markov.jl ruleset1.txt test1.txt |
|||
Using rules from file ruleset1.txt, processing text test1.txt. |
|||
Result of test: I bought a bag of apples from my brother. |
|||
prompt>julia markov.jl ruleset2.txt test2.txt |
|||
Using rules from file ruleset2.txt, processing text test2.txt. |
|||
Result of test: I bought a bag of apples from T shop. |
|||
prompt>julia markov.jl ruleset3.txt test3.txt |
|||
Using rules from file ruleset3.txt, processing text test3.txt. |
|||
Result of test: I bought a bag of apples with my money from T shop. |
|||
prompt>julia markov.jl ruleset4.txt test4.txt |
|||
Using rules from file ruleset4.txt, processing text test4.txt. |
|||
Result of test: 11111111111111111111 |
|||
prompt>julia markov.jl ruleset5.txt test5.txt |
|||
Transformed: |
|||
Using rules from file ruleset5.txt, processing text test5.txt. |
|||
00011H1111000</pre> |
|||
</pre> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |