Execute a Markov algorithm: Difference between revisions
Add Refal
(Add source for Rust) |
Not a robot (talk | contribs) (Add Refal) |
||
(19 intermediate revisions by 9 users not shown) | |||
Line 149:
: <code> 00011H1111000 </code>
<br><br>
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">T Rule
String pattern
String replacement
Bool terminating
F (pattern, replacement, terminating)
.pattern = pattern
.replacement = replacement
.terminating = terminating
F parse(rules)
[Rule] result
L(line) rules.split("\n")
I line.starts_with(‘#’)
L.continue
I line.trim(‘ ’).empty
L.continue
V (pat, rep) = line.split(‘ -> ’)
V terminating = 0B
I rep.starts_with(‘.’)
rep = rep[1..]
terminating = 1B
result.append(Rule(pat, rep, terminating))
R result
F apply(text, rules)
V result = text
V changed = 1B
L changed == 1B
changed = 0B
L(rule) rules
I rule.pattern C result
result = result.replace(rule.pattern, rule.replacement)
I rule.terminating
R result
changed = 1B
L.break
R result
V SampleTexts = [‘I bought a B of As from T S.’,
‘I bought a B of As from T S.’,
‘I bought a B of As W my Bgage from T S.’,
‘_1111*11111_’,
‘000000A000000’]
V RuleSets = [
‘# This rules file is extracted from Wikipedia:
# http://en.wikipedia.org/wiki/Markov_Algorithm
A -> apple
B -> bag
S -> shop
T -> the
the shop -> my brother
a never used -> .terminating rule’,
‘# Slightly modified from the rules on Wikipedia
A -> apple
B -> bag
S -> .shop
T -> the
the shop -> my brother
a never used -> .terminating rule’,
‘# 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’,
‘### 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
_+_ -> ’,
‘# 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’]
L(ruleset) RuleSets
V rules = parse(ruleset)
print(apply(SampleTexts[L.index], rules))</syntaxhighlight>
{{out}}
<pre>
I bought a bag of apples from my brother.
I bought a bag of apples from T shop.
I bought a bag of apples with my money from T shop.
11111111111111111111
00011H1111000
</pre>
=={{header|Ada}}==
markov.ads:
<
package Markov is
Line 177 ⟶ 320:
Entries : Entry_Array (1 .. Length);
end record;
end Markov;</
markov.adb:
<
function Parse (S : String_Array) return Ruleset is
Line 260 ⟶ 403:
end Apply;
end Markov;</
test_markov.adb:
<
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
Line 310 ⟶ 453:
end;
end;
end Test_Markov;</
Output (rulesX contains the ruleset of above examples and testX the example text):
Line 322 ⟶ 465:
11111111111111111111
$ ./test_markov rules5 test5
00011H1111000</pre>
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">markov←{
trim←{(~(∧\∨⌽∘(∧\)∘⌽)⍵∊⎕UCS 9 32)/⍵}
rules←(~rules∊⎕UCS 10 13)⊆rules←80 ¯1 ⎕MAP ⍺
rules←('#'≠⊃¨rules)/rules
rules←{
norm←' '@(9=⎕UCS)⊢⍵
spos←⍸' -> '⍷norm
pat←trim spos↑⍵
repl←trim(spos+2)↓⍵
term←'.'=⊃repl
term pat(term↓repl)
}¨rules
apply←{
0=⍴rule←⍸∨/¨(2⊃¨⍺)⍷¨⊂⍵:⍵
term pat repl←⊃⍺[⊃rule]
idx←(⊃⍸pat⍷⍵)-1
⍺ ∇⍣(~term)⊢(idx↑⍵),repl,(idx+≢pat)↓⍵
}
rules apply ⍵
}</syntaxhighlight>
{{out}}
<pre> 'f:\ruleset1.mkv' markov 'I bought a B of As from T S.'
I bought a bag of apples from my brother.
'f:\ruleset2.mkv' markov 'I bought a B of As from T S.'
I bought a bag of apples from T shop.
'f:\ruleset3.mkv' markov 'I bought a B of As W my Bgage from T S.'
I bought a bag of apples with my money from T shop.
'f:\ruleset4.mkv' markov '_1111*11111_'
11111111111111111111
'f:\ruleset5.mkv' markov '000000A000000'
00011H1111000</pre>
=={{header|AutoHotkey}}==
<
; Markov Algorithm.ahk
; by wolf_II
Line 678 ⟶ 855:
;---------- end of file ----------------------------------------------------</
=={{header|BBC BASIC}}==
<
PRINT FNmarkov("ruleset2.txt", "I bought a B of As from T S.")
PRINT FNmarkov("ruleset3.txt", "I bought a B of As W my Bgage from T S.")
Line 715 ⟶ 892:
UNTIL EOF#rules% OR done%
CLOSE #rules%
= text$</
'''Output:'''
<pre>
Line 727 ⟶ 904:
=={{header|Bracmat}}==
Save the following text to a file "markov.bra":
<
markov=
{
Line 942 ⟶ 1,119:
& ok
| failure;
</syntaxhighlight>
Test:
Line 961 ⟶ 1,138:
=={{header|C}}==
<
#include <stdlib.h>
#include <string.h>
Line 1,163 ⟶ 1,340:
return 0;
}</
text: I bought a B of As from T S.
markoved: I bought a bag of apples from my brother.
Line 1,182 ⟶ 1,359:
text: 000000A000000
markoved: 00011H1111000
</syntaxhighlight>
=={{header|C++}}==
Note: Non-use of <code>iswhite</code> is intentional, since depending on the locale, other chars besides space and tab might be detected by that function.
<
#include <cstdlib>
#include <iostream>
Line 1,299 ⟶ 1,476:
std::cout << output << "\n";
}</
=={{header|CLU}}==
<syntaxhighlight lang="clu">markov = cluster is make, run
rule = struct[from, to: string, term: bool]
rep = array[rule]
% Remove leading and trailing whitespace from a string
trim = proc (s: string) returns (string)
ac = array[char]
sc = sequence[char]
own ws: string := "\n\t "
a: ac := string$s2ac(s)
while ~ac$empty(a) cand string$indexc(ac$bottom(a), ws) ~= 0 do
ac$reml(a)
end
while ~ac$empty(a) cand string$indexc(ac$top(a), ws) ~= 0 do
ac$remh(a)
end
return(string$sc2s(sc$a2s(a)))
end trim
% Parse a single Markov rule
parse = proc (s: string) returns (rule) signals (comment, invalid(string))
if string$empty(s) cor s[1]='#' then signal comment end
arrow: int := string$indexs(" -> ", s)
if arrow=0 then signal invalid(s) end
left: string := trim(string$substr(s, 1, arrow-1))
right: string := trim(string$rest(s, arrow+4))
if ~string$empty(right) cand right[1] = '.' then
right := string$rest(right, 2)
return(rule${from: left, to: right, term: true})
else
return(rule${from: left, to: right, term: false})
end
end parse
% Add a rule to the list
add_rule = proc (m: cvt, s: string) signals (invalid(string))
rep$addh(m, parse(s)) resignal invalid
except when comment: end
end add_rule
% Read rules in sequence from a stream
add_rules = proc (m: cvt, s: stream) signals (invalid(string))
while true do
add_rule(up(m), stream$getl(s)) resignal invalid
except when end_of_file: break end
end
end add_rules
make = proc (s: stream) returns (cvt) signals (invalid(string))
a: rep := rep$new()
add_rules(up(a), s)
return(a)
end make
% Apply a rule to a string
apply_rule = proc (r: rule, s: string) returns (string) signals (no_match)
match: int := string$indexs(r.from, s)
if match = 0 then signal no_match end
new: string := string$substr(s, 1, match-1)
|| r.to
|| string$rest(s, match+string$size(r.from))
return(new)
end apply_rule
% Apply all rules to a string repeatedly
run = proc (c: cvt, s: string) returns (string)
i: int := 1
while i <= rep$high(c) do
r: rule := c[i]
begin
s := apply_rule(r, s)
i := 1
if r.term then break end
end except when no_match:
i := i+1
end
end
return(s)
end run
end markov
start_up = proc ()
po: stream := stream$primary_output()
eo: stream := stream$error_output()
begin
args: sequence[string] := get_argv()
file: string := args[1]
input: string := args[2]
fs: stream := stream$open(file_name$parse(file), "read")
mkv: markov := markov$make(fs)
stream$close(fs)
stream$putl(po, markov$run(mkv, input))
end except
when bounds: stream$putl(eo, "Arguments: markov [filename] [string]")
when not_possible(s: string): stream$putl(eo, "File error: " || s)
when invalid(s: string): stream$putl(eo, "Parse error: " || s)
end
end start_up</syntaxhighlight>
{{out}}
<pre>$ ./markov ruleset1.mkv "I bought a B of As from T S."
I bought a bag of apples from my brother.
$ ./markov ruleset2.mkv "I bought a B of As from T S."
I bought a bag of apples from T shop.
$ ./markov ruleset3.mkv "I bought a B of As W my Bgage from T S."
I bought a bag of apples with my money from T shop.
$ ./markov ruleset4.mkv "_1111*11111_"
11111111111111111111
$ ./markov ruleset5.mkv "000000A000000"
00011H1111000</pre>
=={{header|Common Lisp}}==
I should mention that this uses the regular expression machinery present in Allegro Lisp but not Common Lisp generally (though there are public domain Lisp libraries).
<
(defclass markov ()
((rules :initarg :rules :initform nil :accessor rules)))
Line 1,370 ⟶ 1,664:
(setf ret (adjust rule-info ret))
(if (terminal (car rule-info)) (return ret))
(setf rule-info (get-rule markov ret)))))</
Testing:
<syntaxhighlight lang="text">(defparameter
*rules1*
"# This rules file is extracted from Wikipedia:
Line 1,399 ⟶ 1,693:
00011H1111000
NIL
</syntaxhighlight>
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
include "strings.coh";
include "malloc.coh";
include "argv.coh";
include "file.coh";
record Rule is
pattern: [uint8];
replacement: [uint8];
next: [Rule];
terminates: uint8;
end record;
sub AllocRule(): (rule: [Rule]) is
rule := Alloc(@bytesof Rule) as [Rule];
MemZero(rule as [uint8], @bytesof Rule);
end sub;
sub ParseRule(text: [uint8]): (rule: [Rule]) is
sub ParseError() is
print("Failed to parse rule: ");
print(text);
print_nl();
ExitWithError();
end sub;
var cur := text;
sub SkipWs() is
while [cur] != 0 and [cur] <= ' ' loop cur := @next cur; end loop;
end sub;
sub AllocAndCopy(src: [uint8], length: intptr): (copy: [uint8]) is
copy := Alloc(length + 1);
MemCopy(src, length, copy);
[copy + length] := 0;
end sub;
SkipWs();
if [cur] == '#' or [cur] == 0 then # comment or empty line
rule := 0 as [Rule];
return;
end if;
var patternStart := cur;
# find the " ->"
while [cur] != 0
and ([cur] > ' ' or [cur+1] != '-' or [cur+2] != '>') loop
cur := @next cur;
end loop;
if [cur] == 0 then ParseError(); end if;
# find last char of pattern
var patternEnd := cur;
while patternStart < patternEnd and [patternEnd] <= ' ' loop
patternEnd := @prev patternEnd;
end loop;
cur := cur + 3; # whitespace + '->'
SkipWs();
var replacementStart := cur;
# find last char of replacement
while [cur] != 0 loop cur := @next cur; end loop;
while replacementStart < cur and [cur] <= ' ' loop
cur := @prev cur;
end loop;
# make rule object
rule := AllocRule();
rule.pattern := AllocAndCopy(patternStart, patternEnd-patternStart+1);
if [replacementStart] == '.' then
rule.terminates := 1;
replacementStart := @next replacementStart;
end if;
rule.replacement := AllocAndCopy(replacementStart, cur-replacementStart+1);
end sub;
sub FindMatch(needle: [uint8], haystack: [uint8]): (match: [uint8]) is
match := 0 as [uint8];
while [haystack] != 0 loop
var n := needle;
var h := haystack;
while [n] != 0 and [h] != 0 and [n] == [h] loop
n := @next n;
h := @next h;
end loop;
if [n] == 0 then
match := haystack;
return;
end if;
haystack := @next haystack;
end loop;
end sub;
const NO_MATCH := 0;
const HALT := 1;
const CONTINUE := 2;
sub ApplyRule(rule: [Rule], in: [uint8], out: [uint8]): (result: uint8) is
var match := FindMatch(rule.pattern, in);
if match == 0 as [uint8] then
result := NO_MATCH;
else
var len := StrLen(rule.replacement);
var patlen := StrLen(rule.pattern);
var rest := match + patlen;
MemCopy(in, match-in, out);
MemCopy(rule.replacement, len, out+(match-in));
CopyString(rest, out+(match-in)+len);
if rule.terminates != 0 then
result := HALT;
else
result := CONTINUE;
end if;
end if;
end sub;
sub ApplyRules(rules: [Rule], buffer: [uint8]): (r: [uint8]) is
var outbuf: uint8[256];
var rule := rules;
r := buffer;
while rule != 0 as [Rule] loop
case ApplyRule(rule, buffer, &outbuf[0]) is
when NO_MATCH:
rule := rule.next;
when HALT:
CopyString(&outbuf[0], buffer);
return;
when CONTINUE:
CopyString(&outbuf[0], buffer);
rule := rules;
end case;
end loop;
end sub;
sub ReadFile(filename: [uint8]): (rules: [Rule]) is
var linebuf: uint8[256];
var fcb: FCB;
var bufptr := &linebuf[0];
rules := 0 as [Rule];
var prevRule := 0 as [Rule];
if FCBOpenIn(&fcb, filename) != 0 then
print("Cannot open file: ");
print(filename);
print_nl();
ExitWithError();
end if;
var length := FCBExt(&fcb);
var ch: uint8 := 1;
while length != 0 and ch != 0 loop
ch := FCBGetChar(&fcb);
length := length - 1;
[bufptr] := ch;
bufptr := @next bufptr;
if ch == '\n' then
[bufptr] := 0;
bufptr := &linebuf[0];
var rule := ParseRule(&linebuf[0]);
if rule != 0 as [Rule] then
if rules == 0 as [Rule] then rules := rule; end if;
if prevRule != 0 as [Rule] then prevRule.next := rule; end if;
prevRule := rule;
end if;
end if;
end loop;
var dummy := FCBClose(&fcb);
end sub;
ArgvInit();
var fname := ArgvNext();
if fname == 0 as [uint8] then
print("usage: markov [pattern file] [pattern]\n");
ExitWithError();
end if;
var patbuf: uint8[256];
var patptr := &patbuf[0];
loop
var patpart := ArgvNext();
if patpart == 0 as [uint8] then
if patptr != &patbuf[0] then patptr := @prev patptr; end if;
[patptr] := 0;
break;
end if;
var partlen := StrLen(patpart);
MemCopy(patpart, partlen, patptr);
patptr := patptr + partlen + 1;
[@prev patptr] := ' ';
end loop;
print(ApplyRules(ReadFile(fname), &patbuf[0]));
print_nl();</syntaxhighlight>
{{out}}
<pre>$ ./markov.386 ruleset1.mkv "I bought a B of As from T S."
I bought a bag of apples from my brother.
$ ./markov.386 ruleset2.mkv "I bought a B of As from T S."
I bought a bag of apples from T shop.
$ ./markov.386 ruleset3.mkv "I bought a B of As W my Bgage from T S."
I bought a bag of apples with my money from T shop.
$ ./markov.386 ruleset4.mkv "_1111*11111_"
11111111111111111111
$ ./markov.386 ruleset5.mkv "000000A000000"
00011H1111000</pre>
=={{header|D}}==
{{trans|Perl}}
<
import std.stdio, std.file, std.regex, std.string, std.range,
std.functional;
Line 1,435 ⟶ 1,939:
writefln("%s\n%s\n", origTest, test);
}
}</
{{out}}
<pre>I bought a B of As from T S.
Line 1,454 ⟶ 1,958:
=={{header|Déjà Vu}}==
This implementation expect the initial text on the command line and the ruleset on STDIN.
<
]
for line in text:
Line 1,496 ⟶ 2,000:
not (markov-tick) rules
!. markov markov-parse get-from !args 1</
=={{header|EchoLisp}}==
<
;; rule := (pattern replacement [#t terminal])
Line 1,533 ⟶ 2,037:
(define (task i-string RS)
(markov i-string (parse-rules RS)))
</syntaxhighlight>
{{out}}
<pre>
Line 1,570 ⟶ 2,074:
=={{header|F_Sharp|F#}}==
<p>Using Partial Active Pattern to simplify pattern matching.</p>
<
open System.IO
open System.Text.RegularExpressions
Line 1,622 ⟶ 2,126:
|> run
|> printfn "%s"
0</
{{out}}
<pre>H:\RosettaCode\ExecMarkovAlgo>echo I bought a B of As from T S. | Fsharp\RosettaCode\bin\Debug\RosettaCode.exe m1
Line 1,640 ⟶ 2,144:
=={{header|Go}}==
<
import (
Line 1,815 ⟶ 2,319:
`00011H1111000`,
},
}</
{{out}}
<pre>
Line 1,823 ⟶ 2,327:
=={{header|Groovy}}==
<
def ruleMap = [:]
rules.eachLine { line ->
Line 1,847 ⟶ 2,351:
text
}]
}</
The test code is below (with the markov rulesets 2..5 elided):
<
[withInput: { text ->
[hasOutput: { expected ->
Line 1,881 ⟶ 2,385:
def ruleset5 = markovInterpreterFor("""...""")
verify ruleset5 withInput '000000A000000' hasOutput '00011H1111000'</
{{out}}
<pre>
Line 1,895 ⟶ 2,399:
This program expects a source file as an argument and uses the standard input and output devices for the algorithm's I/O.
<
import Data.Maybe (catMaybes)
import Control.Monad
Line 1,937 ⟶ 2,441:
then let new = reverse before ++ to ++ drop (length from) ahead
in if terminating then new else f rules new
else g (a : before) as</
=={{header|Icon}} and {{header|Unicon}}==
<
rules := loadRules(open(A[1],"r"))
every write(line := !&input, " -> ",apply(rules, line))
Line 1,962 ⟶ 2,466:
if (s == line) | \r.term then return s else line := s
}
end</
Sample runs using above rule sets and test strings:
Line 1,984 ⟶ 2,488:
=={{header|J}}==
'''Solution''':<
markovLexer =: verb define
Line 2,013 ⟶ 2,517:
end.
y
)</
'''Example''':<
# This rules file is extracted from Wikipedia:
# http://en.wikipedia.org/wiki/Markov_Algorithm
Line 2,028 ⟶ 2,532:
m1 markov 'I bought a B of As from T S.'
I bought a bag of apples from my brother.
</syntaxhighlight>
'''Discussion''': The J implementation correctly processes all the rulesets. More details are available on the [[Talk:Markov Algorithm#explicit_vs_tacit|the talk page]].
Line 2,034 ⟶ 2,538:
{{trans|D}}
{{works with|Java|7}}
<
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Line 2,096 ⟶ 2,600:
return rules;
}
}</
Output:
Line 2,116 ⟶ 2,620:
=={{header|JavaScript}}==
<
* Take a ruleset and return a function which takes a string to which the rules
* should be applied.
Line 2,275 ⟶ 2,779:
console.log(markov(ruleset3)('I bought a B of As W my Bgage from T S.'));
console.log(markov(ruleset4)('_1111*11111_'));
console.log(markov(ruleset5)('000000A000000'));</
Output:
<pre>I bought a bag of apples from my brother.
Line 2,282 ⟶ 2,786:
11111111111111111111
00011H1111000</pre>
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
This entry assumes that the rule sets are in a single file (markov_rules.txt);
that the rule sets are separated by a blank line;
and that the corresponding test cases are in a separate file (markov_tests.txt), with one test case per line.
In addition, for simplicity, only blanks are counted as <whitespace>.
With the following program, jq could then be invoked as follows:
<pre>
jq -nrR --rawfile markov_rules markov_rules.txt -f program.jq markov_tests.txt
</pre>
'''Preliminaries'''
<syntaxhighlight lang="jq"># Output: the input string with all its regex-special characters suitably escaped
def deregex:
reduce ("\\\\", "\\*", "\\^", "\\?", "\\+", "\\.", "\\!", "\\{", "\\}", "\\[", "\\]", "\\$", "\\|",
"\\(", "\\)" ) as $c
(.; gsub( $c; $c));
# line-break
def lb: "\n";
def split2($s):
index($s) as $ix
| if $ix then [ .[:$ix], .[$ix + ($s|length):]] else null end;
def trim: sub("^ *";"") | sub(" *$";"");
# rulesets are assumed to be separated by a blank line
# input: a string
def readRules:
trim | split("\(lb)\(lb)") | map(split(lb)) ;
# tests are assumed to be on consecutive lines via `inputs`
# Output: an array
def readTests: [inputs | trim | select(length>0) ];
def rules: $markov_rules | readRules;
def tests: readTests;</syntaxhighlight>
<syntaxhighlight lang="jq">def parseRules($rules):
"^ *(?<period>[.]?) *(?<rule>.*)" as $pattern
| reduce $rules[] as $rule ([];
if $rule | (startswith("#") or (test(" -> ")|not)) then .
else ($rule|split2(" -> ")) as $splits
| ($splits[1] | capture($pattern)) as $re
| . + [[($splits[0]|trim|deregex), $re.period, ($re.rule | trim)]]
end );
# applyRules applies $rules to . recursively,
# where $rules is the set of applicable rules in the form of an array-of-triples.
# Input and output: a string
def applyRules($rules):
# The inner function has arity-0 for efficiency
# input and output: {stop, string}
def apply:
if .stop then .
else .string as $copy
| first( foreach $rules[] as $c (.;
.string |= sub($c[0]; $c[2])
| if $c[1] == "."
then .stop=true
elif .string != $copy
then (apply | .stop = true)
else .
end;
if .stop then . else empty end))
// .
end;
{stop: false, string: .} | apply | .string;
def proceed:
rules as $rules
| tests as $tests
| range(0; $tests|length) as $ix
| $tests[$ix]
| " \(.)\n=>\(applyRules( parseRules( $rules[$ix] ) ))\n" ;
proceed</syntaxhighlight>
{{out}}
<pre>
I bought a B of As from T S.
=>I bought a bag of apples from my brother.
I bought a B of As from T S.
=>I bought a bag of apples from T shop.
I bought a B of As W my Bgage from T S.
=>I bought a bag of apples with my money from T shop.
_1111*11111_
=>11111111111111111111
000000A000000
=>00011H1111000
</pre>
=={{header|Julia}}==
Line 2,287 ⟶ 2,892:
'''Module''':
<
struct MarkovRule{F,T}
Line 2,334 ⟶ 2,939:
end
end # module MarkovAlgos</
'''Main''':
<
let rulesets = @.("data/markovrules0" * string(1:5) * ".txt"),
Line 2,347 ⟶ 2,952:
println("Transformed:\n", MarkovAlgos.apply(ruletest[i], rules))
end
end</
{{out}}
Line 2,387 ⟶ 2,992:
=={{header|Kotlin}}==
{{trans|Java}}
<
import java.io.File
Line 2,430 ⟶ 3,035:
println("$origTest\n$test\n")
}
}</
{{out}}
Line 2,451 ⟶ 3,056:
=={{header|Lua}}==
<
function normalize(str)
local result = str:gsub("(%p)", "%%%1")
Line 2,635 ⟶ 3,240:
do_markov(grammar3, text2, 'I bought a bag of apples with my money from T shop.')
do_markov(grammar4, text3, '11111111111111111111')
do_markov(grammar5, text4, '00011H1111000')</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
Module[{terminating = False, output = text,
rules = StringCases[
Line 2,649 ⟶ 3,254:
output = StringReplace[output, rule[[1]] -> rule[[2]]];
If[! rule[[3]], terminating = False]; Break[]], {rule, rules}]];
output];</
Example:
<
#
# state A, symbol 0 => write 1, move right, new state B
Line 2,668 ⟶ 3,273:
# state C, symbol 1 => write 1, move left, halt
0C1 -> H01
1C1 -> H11", "000000A000000"]</
Output:
<pre>"00011H1111000"</pre>
=={{header|МК-61/52}}==
<syntaxhighlight lang="text"> 9 П4
КИП4 [x] П7 Вx {x} П8
ИП8 ИПE * П8 {x} x=0 08
Line 2,693 ⟶ 3,298:
ИП3 ИПE / [x] П3
x=0 22
ИП4 ИП0 - 9 - x=0 02 С/П</
Under the rules of left 4 registers, under the word has 8 character cells, the alphabet of the digits from 1 to 8. Rules are placed in "123,456", where "123" is a fragment, and "456" is to be replaced, in the registers of the РA to РD. The number of rules is stored in Р0, the initial word is in Р9. Number triggered rule is the last digit registration Р4 (0 to 3), if no rule did not work, the indicator 0, otherwise the current word to be processed. In РE is stored 10.
=={{header|Nim}}==
<syntaxhighlight lang="nim">import strutils, strscans
type Rule = object
pattern: string # Input pattern.
replacement: string # Replacement string (may be empty).
terminating: bool # "true" if terminating rule.
#---------------------------------------------------------------------------------------------------
func parse(rules: string): seq[Rule] =
## Parse a rule set to build a sequence of rules.
var linecount = 0
for line in rules.splitLines():
inc linecount
if line.startsWith('#'): continue
if line.strip.len == 0: continue
# Scan the line.
var pat, rep: string
var terminating = false
if not line.scanf("$+ -> $*", pat, rep):
raise newException(ValueError, "Invalid rule at line " & $linecount)
if rep.startsWith('.'):
# Terminating rule.
rep = rep[1..^1]
terminating = true
result.add(Rule(pattern: pat, replacement: rep, terminating: terminating))
#---------------------------------------------------------------------------------------------------
func apply(text: string; rules: seq[Rule]): string =
## Apply a set of rules to a text and return the result.
result = text
var changed = true
while changed:
changed = false
# Try to apply the rules in sequence.
for rule in rules:
if result.find(rule.pattern) >= 0:
# Found a rule to apply.
result = result.replace(rule.pattern, rule.replacement)
if rule.terminating: return
changed = true
break
#———————————————————————————————————————————————————————————————————————————————————————————————————
const SampleTexts = ["I bought a B of As from T S.",
"I bought a B of As from T S.",
"I bought a B of As W my Bgage from T S.",
"_1111*11111_",
"000000A000000"]
const Rulesets = [
#................................................
"""# This rules file is extracted from Wikipedia:
# http://en.wikipedia.org/wiki/Markov_Algorithm
A -> apple
B -> bag
S -> shop
T -> the
the shop -> my brother
a never used -> .terminating rule""",
#................................................
"""# Slightly modified from the rules on Wikipedia
A -> apple
B -> bag
S -> .shop
T -> the
the shop -> my brother
a never used -> .terminating rule""",
#................................................
"""# 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""",
#................................................
"""### 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
_+_ -> """,
#................................................
"""# 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"""
]
for n, ruleset in RuleSets:
let rules = ruleset.parse()
echo SampleTexts[n].apply(rules)</syntaxhighlight>
{{out}}
<pre>I bought a bag of apples from my brother.
I bought a bag of apples from T shop.
I bought a bag of apples with my money from T shop.
11111111111111111111
00011H1111000</pre>
=={{header|OCaml}}==
Line 2,701 ⟶ 3,468:
I'm not familiar with string processing, or parsing, so there are probably better ways to express this in OCaml. One might be with the mikmatch library which allows pattern-matching with regexps. Here I've only used the OCaml stdlib...
<
let try_finally x f g =
try let res = f x in g x; res
Line 2,748 ⟶ 3,515:
print_endline (run rules (input_line stdin));
translate ()
in try translate () with End_of_file -> ()</
With the above compiled to an executable 'markov', and the five rule-sets in files, strings are accepted on stdin for translation:
Line 2,771 ⟶ 3,538:
000000A000000
00011H1111000
</pre>
=={{header|Pascal}}==
{{works with|FPC}}
<syntaxhighlight lang="pascal">
program InterpretMA;
{$mode objfpc}{$h+}{$j-}{$b-}
uses
SysUtils;
type
TRule = record
Pattern, Replacement: string;
Terminating: Boolean;
end;
function ParseMA(const aScheme: string; out aRules: specialize TArray<TRule>): Boolean;
function ParseLine(const s: string; out r: TRule): Boolean;
var
Terms: TStringArray;
begin
Terms := s.Split([' -> ']);
if Length(Terms) <> 2 then exit(False);
r.Pattern := Terms[0].Trim;
r.Replacement := Terms[1].Trim;
r.Terminating := False;
if (r.Replacement <> '') and (r.Replacement[1] = '.') then begin
r.Terminating := True;
Delete(r.Replacement, 1, 1);
end;
Result := True;
end;
var
Lines: TStringArray;
s: string;
I: Integer;
begin
aRules := nil;
if aScheme = '' then exit(False);
Lines := aScheme.Split([LineEnding], TStringSplitOptions.ExcludeEmpty);
if Lines = nil then exit(False);
SetLength(aRules, Length(Lines));
I := 0;
for s in Lines do begin
if s[1] = '#' then continue;
if not ParseLine(s, aRules[I]) then exit(False);
Inc(I);
end;
SetLength(aRules, I);
Result := True;
end;
function ExecuteMA(const aScheme, aInput: string): string;
var
Rules: array of TRule;
r: TRule;
Applied: Boolean;
begin
if not ParseMA(aScheme.Replace(#9, ' ', [rfReplaceAll]), Rules) then
exit('Error while parsing MA scheme');
Result := aInput;
repeat
Applied := False;
for r in Rules do begin
if r.Pattern = '' then begin
Result := r.Replacement + Result;
Applied := True;
end else begin
Applied := Result.IndexOf(r.Pattern) >= 0;
if Applied then
Result := Result.Replace(r.Pattern, r.Replacement);
end;
if Applied then begin
if r.Terminating then exit;
break;
end;
end;
until not Applied;
end;
type
TTestEntry = record
Scheme, Input, Output: string;
end;
const
LE = LineEnding;
TestSet: array[1..5] of TTestEntry = (
(Scheme:
'# This rules file is extracted from Wikipedia: ' +LE+
'# http://en.wikipedia.org/wiki/Markov_Algorithm' +LE+
'A -> apple' +LE+
'B -> bag' +LE+
'S -> shop' +LE+
'T -> the' +LE+
'the shop -> my brother' +LE+
'a never used -> .terminating rule';
Input: 'I bought a B of As from T S.'; Output: 'I bought a bag of apples from my brother.'),
(Scheme:
'# Slightly modified from the rules on Wikipedia' +LE+
'A -> apple' +LE+
'B -> bag' +LE+
'S -> .shop' +LE+
'T -> the' +LE+
'the shop -> my brother' +LE+
'a never used -> .terminating rule';
Input: 'I bought a B of As from T S.'; Output: 'I bought a bag of apples from T shop.'),
(Scheme:
'# BNF Syntax testing rules' +LE+
'A -> apple' +LE+
'WWWW -> with' +LE+
'Bgage -> ->.*' +LE+
'B -> bag' +LE+
'->.* -> money' +LE+
'W -> WW' +LE+
'S -> .shop' +LE+
'T -> the' +LE+
'the shop -> my brother' +LE+
'a never used -> .terminating rule';
Input: 'I bought a B of As W my Bgage from T S.'; Output: 'I bought a bag of apples with my money from T shop.'),
(Scheme:
'### Unary Multiplication Engine, for testing Markov Algorithm implementations' +LE+
'### By Donal Fellows.' +LE+
'# Unary addition engine' +LE+
'_+1 -> _1+' +LE+
'1+1 -> 11+' +LE+
'# Pass for converting from the splitting of multiplication into ordinary' +LE+
'# addition' +LE+
'1! -> !1' +LE+
',! -> !+' +LE+
'_! -> _' +LE+
'# Unary multiplication by duplicating left side, right side times' +LE+
'1*1 -> x,@y' +LE+
'1x -> xX' +LE+
'X, -> 1,1' +LE+
'X1 -> 1X' +LE+
'_x -> _X' +LE+
',x -> ,X' +LE+
'y1 -> 1y' +LE+
'y_ -> _' +LE+
'# Next phase of applying' +LE+
'1@1 -> x,@y' +LE+
'1@_ -> @_' +LE+
',@_ -> !_' +LE+
'++ -> +' +LE+
'# Termination cleanup for addition' +LE+
'_1 -> 1' +LE+
'1+_ -> 1' +LE+
'_+_ -> ';
Input: '_1111*11111_'; Output: '11111111111111111111'),
(Scheme:
'# Turing machine: three-state busy beaver' +LE+
'#' +LE+
'# state A, symbol 0 => write 1, move right, new state B' +LE+
'A0 -> 1B' +LE+
'# state A, symbol 1 => write 1, move left, new state C' +LE+
'0A1 -> C01' +LE+
'1A1 -> C11' +LE+
'# state B, symbol 0 => write 1, move left, new state A' +LE+
'0B0 -> A01' +LE+
'1B0 -> A11' +LE+
'# state B, symbol 1 => write 1, move right, new state B' +LE+
'B1 -> 1B' +LE+
'# state C, symbol 0 => write 1, move left, new state B' +LE+
'0C0 -> B01' +LE+
'1C0 -> B11' +LE+
'# state C, symbol 1 => write 1, move left, halt' +LE+
'0C1 -> H01' +LE+
'1C1 -> H11';
Input: '000000A000000'; Output: '00011H1111000')
);
E_FMT = 'test #%d: expected "%s", but got "%s"';
var
e: TTestEntry;
Result: string;
I: Integer = 1;
Failed: Integer = 0;
begin
for e in TestSet do begin
Result := ExecuteMA(e.Scheme, e.Input);
if Result <> e.Output then begin
WriteLn(Format(E_FMT, [I, e.Output, Result]));
Inc(Failed);
end;
Inc(I);
end;
WriteLn('tests completed: ', Length(TestSet), ', failed: ', Failed);
end.
</syntaxhighlight>
{{out}}
<pre>
tests completed: 5, failed: 0
</pre>
Line 2,776 ⟶ 3,735:
This program expects a source file as an argument and uses the standard input and output devices for the algorithm's I/O.
<
open my $source, '<', $ARGV[0] or die "I couldn't open \"$ARGV[0]\" for reading. ($!.)\n";
my @rules;
Line 2,793 ⟶ 3,752:
and ($terminating ? last OUTER : redo OUTER);}}
print $input;</
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">procedure</span> <span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">rules</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">input</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">expected</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">subs</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">reps</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rules</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\t'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">),</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'#'</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #008000;">" -> "</span><span style="color: #0000FF;">,</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">subs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">subs</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]))</span>
<span style="color: #000000;">reps</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">reps</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">..$]))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">input</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">term</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">subs</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">sub</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">subs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sub</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">rep</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">reps</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rep</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">rep</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">rep</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rep</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
<span style="color: #000000;">term</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sub</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rep</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">term</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">term</span> <span style="color: #008080;">or</span> <span style="color: #008080;">not</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">input</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #000000;">expected</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"ok"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"**ERROR**"</span><span style="color: #0000FF;">)}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ruleset1</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
# This rules file is extracted from Wikipedia:
# http://en.wikipedia.org/wiki/Markov_Algorithm
T -> the
the shop -> my brother
a never used -> .terminating rule"""</span>
<span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ruleset1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a B of As from T S."</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a bag of apples from my brother."</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ruleset2</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
# Slightly modified from the rules on Wikipedia
T -> the
the shop -> my brother
a never used -> .terminating rule"""</span>
<span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ruleset2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a B of As from T S."</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a bag of apples from T shop."</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ruleset3</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
# BNF Syntax testing rules
A -> apple
WWWW -> with
Bgage -> ->.*
B -> bag
->.* -> money
T -> the
the shop -> my brother
a never used -> .terminating rule"""</span>
<span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ruleset3</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a B of As W my Bgage from T S."</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I bought a bag of apples with my money from T shop."</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ruleset4</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
### Unary Multiplication Engine, for testing Markov Algorithm implementations
### By Donal Fellows.
# Unary addition engine
1+1 -> 11+
# Pass for converting from the splitting of multiplication into ordinary
# addition
_! -> _
# Unary multiplication by duplicating left side, right side times
1*1 -> x,@y
y_ -> _
# Next phase of applying
1@
++ -> +
# Termination cleanup for addition
_+_ ->
"""</span>
<span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ruleset4</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"_1111*11111_"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"11111111111111111111"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ruleset5</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
# 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
1A1 -> C11
# state B, symbol 0 => write 1, move left, new state A
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
1C0 -> B11
# state C, symbol 1 => write 1, move left, halt
1C1 -> H11
"""</span>
<span style="color: #000000;">markov</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ruleset5</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"000000A000000"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"00011H1111000"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,932 ⟶ 3,893:
=={{header|PHP}}==
<
function markov($text, $ruleset) {
Line 3,078 ⟶ 4,039:
foreach ($conf AS $id => $rule) {
echo 'Ruleset ', $id, ' : ', markov($rule['text'], $rule['rule']), PHP_EOL;
}</
{{out}}
Line 3,089 ⟶ 4,050:
=={{header|PicoLisp}}==
<
(use (@A @Z R)
(let Rules
Line 3,107 ⟶ 4,068:
(T (= "." (cadr (setq R @)))
(append @A (cddr R) @Z) )
(setq Text (append @A (cdr R) @Z)) ) ) ) ) )</
Output:
<pre>: (markov "r1" "I bought a B of As from T S.")
Line 3,128 ⟶ 4,089:
Module lambda can be found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
<
:- use_module(library(lambda)).
Line 3,216 ⟶ 4,177:
replacement([X | R]) --> [X], {X \= '\n'}, replacement(R).
replacement([]) --> [].
</syntaxhighlight>
Code to test :
<
:- use_module(library(lambda)).
Line 3,335 ⟶ 4,296:
writeln(B),
writeln(R).
</syntaxhighlight>
Output :
<pre> ?- markov.
Line 3,363 ⟶ 4,324:
=={{header|PureBasic}}==
The GUI used here allows a ruleset to be loaded from a text file or manually added one rule at a time. Symbol input can be tested anytime by selecting 'Interpret'.
<
pattern.s
replacement.s
Line 3,476 ⟶ 4,437:
EndSelect
Until isDone
</syntaxhighlight>
Sample output from loading Ruleset 1 and interpreting a symbol:
<pre>Comment: "# This rules file is extracted from Wikipedia:"
Line 3,495 ⟶ 4,456:
The example gains flexibility by not being tied to specific files. The functions may be imported into other programs which then can provide textual input from their sources without the need to pass 'file handles' around.
<
def extractreplacements(grammar):
Line 3,628 ⟶ 4,589:
== '11111111111111111111'
assert replace(text4, extractreplacements(grammar5)) \
== '00011H1111000'</
=={{header|Racket}}==
Line 3,636 ⟶ 4,597:
The <tt>Markov-algorithm</tt> for a set of rules returns a function which maps from a string to string and can be used as a first-class object. Rules are represented by abstract data structures.
<
#lang racket
Line 3,665 ⟶ 4,626:
(let loop ([x x0] [fx (f x0)])
(if (equal? x fx) fx (loop fx (f fx)))))
</syntaxhighlight>
Example of use:
<
> (define MA
(Markov-algorithm
Line 3,681 ⟶ 4,642:
> (MA "I bought a B of As from T S.")
"I bought a bag of apples from T shop."
</syntaxhighlight>
===The source reader===
Line 3,687 ⟶ 4,648:
To read from a file just replace <tt>with-input-from-string</tt> ==> <tt>with-input-from-file</tt>.
<
;; the reader
(define (read-rules source)
Line 3,710 ⟶ 4,671:
(define (read-Markov-algorithm source)
(apply Markov-algorithm (read-rules source)))
</syntaxhighlight>
Examples:
<
(define R3 (read-Markov-algorithm "
# BNF Syntax testing rules
Line 3,779 ⟶ 4,740:
0C1 -> H01
1C1 -> H11"))
</syntaxhighlight>
<
> (R3 "I bought a B of As W my Bgage from T S.")
"I bought a bag of apples with my money from T shop."
Line 3,790 ⟶ 4,751:
> (R5 "000000A000000")
"00011H1111000"
</syntaxhighlight>
=={{header|Raku}}==
Line 3,800 ⟶ 4,761:
Add --verbose to see the replacements step-by-step.
<syntaxhighlight lang="raku"
token TOP {
^ [^^ [<rule> | <comment>] $$ [\n|$]]* $
Line 3,864 ⟶ 4,825:
say "starting with: $start_value";
say run(:$ruleset, :$start_value, :$verbose);
}</
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
, <Arg 1>: e.File
, <Arg 2>: e.Input
, <ReadLines 1 e.File>: e.Lines
, <Each ParseRule e.Lines>: e.Rules
, <Apply (e.Rules) e.Input>: e.Result
= <Prout e.Result>;
};
Each {
s.F = ;
s.F (e.I) e.R = <Mu s.F e.I> <Each s.F e.R>;
};
ReadLines {
s.Chan e.File = <Open 'r' s.Chan e.File>
<ReadLines (s.Chan)>;
(s.Chan), <Get s.Chan>: {
0 = <Close s.Chan>;
e.Line = (e.Line) <ReadLines (s.Chan)>;
};
};
ParseRule {
= (Empty);
'#' e.X = (Empty);
e.Pat ' -> ' e.Rep,
<Trim e.Pat>: e.TrPat,
<Trim e.Rep>: e.TrRep,
e.TrRep: {
'.' e.R = (Term (e.Pat) (e.R));
e.R = (Nonterm (e.Pat) (e.R));
};
};
ApplyRule {
(s.Type (e.Pat) (e.Rep)) e.Subj,
e.Subj: e.X e.Pat e.Y = s.Type e.X e.Rep e.Y;
t.Rule e.Subj = NoMatch e.Subj;
};
Apply {
(e.Rules) () e.Subj = e.Subj;
(e.Rules) (t.Rule e.Rest) e.Subj,
<ApplyRule t.Rule e.Subj>: {
NoMatch e.Subj = <Apply (e.Rules) (e.Rest) e.Subj>;
Term e.Res = e.Res;
Nonterm e.Res = <Apply (e.Rules) e.Res>;
};
(e.Rules) e.Subj = <Apply (e.Rules) (e.Rules) e.Subj>;
};
Trim {
' ' e.X = <Trim e.X>;
e.X ' ' = <Trim e.X>;
e.X = e.X;
};</syntaxhighlight>
{{out}}
<pre>$ refgo markov ruleset1.mkv 'I bought a B of As from T S.'
I bought a bag of apples from my brother.
$ refgo markov ruleset2.mkv 'I bought a B of As from T S.'
I bought a bag of apples from T shop.
$ refgo markov ruleset3.mkv 'I bought a B of As W my Bgage from T S.'
I bought a bag of apples with my money from T shop.
$ refgo markov ruleset4.mkv '_111*11111_'
111111111111111
$ refgo markov ruleset5.mkv '000000A000000'
00011H1111000</pre>
=={{header|REXX}}==
Code was added to the REXX example to optionally list the contents of the ruleset and/or the Markov entries.
<br>Also, blank lines in the ruleset were treated as comments.
<
parse arg low high . /*allows which ruleset to process. */
if low=='' | low=="," then low=1 /*Not specified? Then use the default.*/
Line 3,910 ⟶ 4,941:
@.r=linein(rFID); if tellR then say 'ruleSet' ?"."left(r,4) '───►' @.r
end /*r*/ /* [↑] read and maybe echo the rule. */
return</
Some older REXXes don't have a '''changestr''' BIF, so one is included here ──► [[CHANGESTR.REX]].
<br><br>
Line 3,933 ⟶ 4,964:
=={{header|Ruby}}==
{{works with|Ruby|
<
ruleset.each_line.inject([]) do |rules, line|
if line =~ /^\s*#/
Line 3,946 ⟶ 4,977:
end
def
rules = setup(ruleset)
while (matched = rules.find { |match, replace, term|
Line 3,953 ⟶ 4,984:
end
input_data
end</
'''Test:'''
<
# This rules file is extracted from Wikipedia:
# http://en.wikipedia.org/wiki/Markov_Algorithm
Line 3,967 ⟶ 4,998:
EOS
puts
ruleset2 = <<EOS
Line 3,979 ⟶ 5,010:
EOS
puts
ruleset3 = <<EOS
Line 3,995 ⟶ 5,026:
EOS
puts
ruleset4 = <<EOS
Line 4,028 ⟶ 5,059:
EOS
puts
ruleset5 = <<EOS
Line 4,051 ⟶ 5,082:
EOS
puts
{{out}}
Line 4,061 ⟶ 5,092:
00011H1111000
</pre>
=={{header|Rust}}==
<
#[derive(Clone, Debug)]
Line 4,295 ⟶ 5,325:
}
}
</syntaxhighlight>
=={{header|Scala}}==
{{works with|Scala|2.8}}
<
object MarkovAlgorithm {
Line 4,328 ⟶ 5,358:
println(algorithm(args(1)))
}
}</
Script-style, and more concise:
<
if (argv.size != 2 ) error("Syntax: MarkovAlgorithm inputFile inputPattern")
Line 4,347 ⟶ 5,377:
println(argv(1))
println(algorithm(argv(1)))</
Sample outputs:
Line 4,375 ⟶ 5,405:
The following implementation uses several string-related procedures provided by SRFI-13 [http://srfi.schemers.org/srfi-13/srfi-13.html].
<
(define split-into-lines
(lambda (str)
Line 4,423 ⟶ 5,453:
rules))
(loop (cdr remaining) result)))))))
</syntaxhighlight>
=={{header|SequenceL}}==
<syntaxhighlight lang="sequencel">
import <Utilities/Sequence.sl>;
Line 4,476 ⟶ 5,506:
replaceSubString(str, original, new, n + 1);
</syntaxhighlight>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program markov_algorithm;
magic := false;
if command_line(1) = om then
print("error: no ruleset file given");
stop;
elseif command_line(2) = om then
print("error: no input string given");
stop;
end if;
rules := read_file(command_line(1));
input := command_line(2);
loop do
loop for [pat, repl, trm] in rules do
if pat in input then
input(pat) := repl;
if trm then
quit;
else
continue loop do;
end if;
end if;
end loop;
quit;
end loop;
print(input);
proc read_file(file_name);
if (rulefile := open(file_name, "r")) = om then
print("error: cannot open ruleset file");
stop;
end if;
rules := [];
loop doing
line := getline(rulefile);
while line /= om do
rule := parse_rule(line);
if rule /= om then rules with:= rule; end if;
end loop;
return rules;
end proc;
proc parse_rule(rule);
if rule(1) = "#" then return om; end if; $ comment
if " -> " notin rule then return om; end if; $ not a rule
[s, e] := mark(rule, " -> ");
pattern := rule(..s-1);
repl := rule(e+1..);
whitespace := "\t\r\n ";
span(pattern, whitespace);
rspan(pattern, whitespace);
span(repl, whitespace);
rspan(repl, whitespace);
trm := match(repl, ".") /= "";
return [pattern, repl, trm];
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>$ setl markov.setl ruleset1.mkv "I bought a B of As from T S."
I bought a bag of apples from my brother.
$ setl markov.setl ruleset2.mkv "I bought a B of As from T S."
I bought a bag of apples from T shop.
$ setl markov.setl ruleset3.mkv "I bought a B of As W my Bgage from T S."
I bought a bag of apples with my money from T shop.
$ setl markov.setl ruleset4.mkv "_1111*11111_"
11111111111111111111
$ setl markov.setl ruleset5.mkv "000000A000000"
00011H1111000</pre>
=={{header|SNOBOL4}}==
Note that the run-time data is immediately after the "end" label. This works with CSNOBOL4, on a Unix (or Unix-like) platform.
The Markov rules are actually compiled into the program after parsing, and are then directly executed (self-modifying code).
<syntaxhighlight lang="snobol4">
#!/bin/sh
exec "snobol4" "-r" "$0" "$@"
Line 4,610 ⟶ 5,715:
000000A000000
END
</syntaxhighlight>
=={{header|Swift}}==
{{trans|Ruby}}
<
func setup(ruleset: String) -> [(String, String, Bool)] {
Line 4,659 ⟶ 5,764:
}
</syntaxhighlight>
{{out}}
<pre>
Line 4,671 ⟶ 5,776:
=={{header|Tcl}}==
{{works with|Tcl|8.5}}
<
if {$argc < 3} {error "usage: $argv0 ruleFile inputFile outputFile"}
lassign $argv ruleFile inputFile outputFile
Line 4,711 ⟶ 5,816:
puts $out $line
}
close $out</
In the case where there are no terminating rules and no overlapping issues, the following is an alternative:
<
if {$argc < 3} {error "usage: $argv0 ruleFile inputFile outputFile"}
lassign $argv ruleFile inputFile outputFile
Line 4,740 ⟶ 5,845:
}
puts $out $data
close $out</
=={{header|VBScript}}==
====Implementation====
<syntaxhighlight lang="vb">
class markovparser
Line 4,818 ⟶ 5,923:
end function
end class
</syntaxhighlight>
=====Invocation=====
<syntaxhighlight lang="vb">
dim m1
set m1 = new markovparser
Line 4,882 ⟶ 5,987:
m5.ruleset = fso.opentextfile("busybeaver.tur").readall
wscript.echo m5.apply("000000A000000")
</syntaxhighlight>
=====Output=====
<syntaxhighlight lang="vb">
I bought a bag of apples from my brother.
I bought a bag of apples from T shop.
Line 4,891 ⟶ 5,996:
11111111111111111111
00011H1111000
</syntaxhighlight>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-ioutil}}
{{libheader|wren-pattern}}
<syntaxhighlight lang="wren">import "./ioutil" for FileUtil, File
import "./pattern" for Pattern
var lb = FileUtil.lineBreak
/* rulesets assumed to be separated by a blank line in file */
var readRules = Fn.new { |path|
return File.read(path).trimEnd().split("%(lb)%(lb)").map { |rs| rs.split(lb) }.toList
}
/* tests assumed to be on consecutive lines */
var readTests = Fn.new { |path| File.read(path).trimEnd().split(lb) }
var rules = readRules.call("markov_rules.txt")
var tests = readTests.call("markov_tests.txt")
var pattern = Pattern.new("+0/s[~.][+0/z]", Pattern.start)
var ix = 0
for (origTest in tests) {
var captures = []
for (rule in rules[ix]) {
if (rule.startsWith("#")) continue
var splits = rule.split(" -> ")
var m = pattern.find(splits[1])
if (m) captures.add([splits[0].trimEnd()] + m.capsText)
}
var test = origTest
while (true) {
var copy = test
var redo = false
for (c in captures) {
test = test.replace(c[0], c[2])
if (c[1] == ".") break
if (test != copy) {
redo = true
break
}
}
if (!redo) break
}
System.print("%(origTest)\n%(test)\n")
ix = ix + 1
}</syntaxhighlight>
{{out}}
<pre>
I bought a B of As from T S.
I bought a bag of apples from my brother.
I bought a B of As from T S.
I bought a bag of apples from T shop.
I bought a B of As W my Bgage from T S.
I bought a bag of apples with my money from T shop.
_1111*11111_
11111111111111111111
000000A000000
00011H1111000
</pre>
=={{header|zkl}}==
<
if(vm.numArgs>1) lines=vm.arglist; // lines or object
ks:=L(); vs:=L();
Line 4,919 ⟶ 6,089:
}while(go);
text
}</
<
"# http://en.wikipedia.org/wiki/Markov_Algorithm",
"A\t->\tapple", "B -> bag", "S -> shop", "T -> the",
"the shop -> my brother", "a never used -> .terminating rule");
ruleSet.println();
markov("I bought a B of As from T S.",ruleSet).println();</
{{out}}
<pre>
Line 4,931 ⟶ 6,101:
I bought a bag of apples from my brother.
</pre>
<
T("# Slightly modified from the rules on Wikipedia",
"A -> apple", "B -> bag", "S -> .shop", "T -> the",
Line 4,941 ⟶ 6,111:
"W -> WW", "S -> .shop", "T -> the",
"the shop -> my brother", "a never used -> .terminating rule") :
markov("I bought a B of As W my Bgage from T S.",_).println();</
{{out}}
<pre>
Line 4,948 ⟶ 6,118:
</pre>
For the next two tasks, read the rule set from a file.
<
parseRuleSet(File("ruleSet5")) : markov("000000A000000",_).println();</
{{out}}
<pre>
|