September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,91 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
ruleSet, sample, output string
|
||||
}
|
||||
|
||||
var testSet []testCase // initialized in separate source file
|
||||
|
||||
func main() {
|
||||
fmt.Println("validating", len(testSet), "test cases")
|
||||
var failures bool
|
||||
for i, tc := range testSet {
|
||||
if r := ma(tc.ruleSet, tc.sample); r != tc.output {
|
||||
fmt.Println("test", i+1, "fail")
|
||||
failures = true
|
||||
}
|
||||
}
|
||||
if !failures {
|
||||
fmt.Println("no failures")
|
||||
}
|
||||
}
|
||||
|
||||
type rule struct {
|
||||
pat string
|
||||
rep string
|
||||
term bool
|
||||
}
|
||||
|
||||
func ma(rs, s string) string {
|
||||
// compile rules per task description
|
||||
var rules []rule
|
||||
for _, line := range strings.Split(rs, "\n") {
|
||||
if line == "" || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
a := strings.Index(line, "->")
|
||||
if a == -1 {
|
||||
fmt.Println("invalid rule:", line)
|
||||
return ""
|
||||
|
||||
}
|
||||
pat := line[:a]
|
||||
for {
|
||||
if pat == "" {
|
||||
b := strings.Index(line[a+2:], "->")
|
||||
if b == -1 {
|
||||
fmt.Println("invalid rule:", line)
|
||||
return ""
|
||||
}
|
||||
a += 2 + b
|
||||
pat = line[:a]
|
||||
continue
|
||||
}
|
||||
last := pat[len(pat)-1]
|
||||
if last != ' ' && last != '\t' {
|
||||
break
|
||||
}
|
||||
pat = pat[:len(pat)-1]
|
||||
}
|
||||
rep := line[a+2:]
|
||||
for rep > "" && (rep[0] == ' ' || rep[0] == '\t') {
|
||||
rep = rep[1:]
|
||||
}
|
||||
var term bool
|
||||
if rep > "" && rep[0] == '.' {
|
||||
term = true
|
||||
rep = rep[1:]
|
||||
}
|
||||
rules = append(rules, rule{pat, rep, term})
|
||||
}
|
||||
// execute algorithm per WP
|
||||
for r := 0; r < len(rules); {
|
||||
pat := rules[r].pat
|
||||
if f := strings.Index(s, pat); f == -1 {
|
||||
r++
|
||||
} else {
|
||||
|
||||
s = s[:f] + rules[r].rep + s[f+len(pat):]
|
||||
if rules[r].term {
|
||||
break
|
||||
}
|
||||
r = 0
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package main
|
||||
|
||||
func init() {
|
||||
testSet = []testCase{
|
||||
{
|
||||
`# 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`,
|
||||
"I bought a B of As from T S.",
|
||||
"I bought a bag of apples from my brother."},
|
||||
{
|
||||
`# Slightly modified from the rules on Wikipedia
|
||||
A -> apple
|
||||
B -> bag
|
||||
...
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
procedure markov(string rules, input, expected)
|
||||
sequence subs = {}, reps = {}
|
||||
sequence lines = split(substitute(rules,"\t"," "),'\n')
|
||||
for i=1 to length(lines) do
|
||||
string li = lines[i]
|
||||
if length(li) and li[1]!='#' then
|
||||
integer k = match(" -> ",li)
|
||||
if k then
|
||||
subs = append(subs,trim(li[1..k-1]))
|
||||
reps = append(reps,trim(li[k+4..$]))
|
||||
end if
|
||||
end if
|
||||
end for
|
||||
string res = input
|
||||
bool term = false
|
||||
while 1 do
|
||||
bool found = false
|
||||
for i=1 to length(subs) do
|
||||
string sub = subs[i]
|
||||
integer k = match(sub,res)
|
||||
if k then
|
||||
found = true
|
||||
string rep = reps[i]
|
||||
if length(rep) and rep[1]='.' then
|
||||
rep = rep[2..$]
|
||||
term = true
|
||||
end if
|
||||
res[k..k+length(sub)-1] = rep
|
||||
exit
|
||||
end if
|
||||
if term then exit end if
|
||||
end for
|
||||
if term or not found then exit end if
|
||||
end while
|
||||
?{input,res,iff(res=expected?"ok":"**ERROR**")}
|
||||
end procedure
|
||||
|
||||
constant ruleset1 = """
|
||||
# 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"""
|
||||
markov(ruleset1,"I bought a B of As from T S.","I bought a bag of apples from my brother.")
|
||||
|
||||
constant ruleset2 = """
|
||||
# Slightly modified from the rules on Wikipedia
|
||||
A -> apple
|
||||
B -> bag
|
||||
S -> .shop
|
||||
T -> the
|
||||
the shop -> my brother
|
||||
a never used -> .terminating rule"""
|
||||
markov(ruleset2,"I bought a B of As from T S.","I bought a bag of apples from T shop.")
|
||||
|
||||
constant ruleset3 = """
|
||||
# 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"""
|
||||
markov(ruleset3,"I bought a B of As W my Bgage from T S.","I bought a bag of apples with my money from T shop.")
|
||||
|
||||
constant ruleset4 = """
|
||||
### 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
|
||||
_+_ ->
|
||||
"""
|
||||
markov(ruleset4,"_1111*11111_","11111111111111111111")
|
||||
|
||||
constant ruleset5 = """
|
||||
# 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
|
||||
"""
|
||||
markov(ruleset5,"000000A000000","00011H1111000")
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import <Utilities/Sequence.sl>;
|
||||
|
||||
Rule ::= ( pattern : char(1),
|
||||
replacement : char(1),
|
||||
terminal : bool);
|
||||
|
||||
ReplaceResult ::= (newString : char(1), wasReplaced : bool);
|
||||
|
||||
main(args(2)) := markov(createRule(split(args[1], '\n')), 1, args[2]);
|
||||
|
||||
createRule(line(1)) :=
|
||||
let
|
||||
containsComments := firstIndexOf(line, '#');
|
||||
removedComments := line when containsComments = 0 else
|
||||
line[1 ... containsComments - 1];
|
||||
|
||||
arrowLocation := startOfArrow(removedComments, 1);
|
||||
lhs := removedComments[1 ... arrowLocation-1];
|
||||
rhs := removedComments[arrowLocation + 4 ... size(removedComments)];
|
||||
isTerminal := size(rhs) > 0 and rhs[1] = '.';
|
||||
in
|
||||
(pattern : lhs,
|
||||
replacement : rhs[2 ... size(rhs)] when isTerminal else rhs,
|
||||
terminal : isTerminal) when size(removedComments) > 0 and arrowLocation /= -1;
|
||||
|
||||
startOfArrow(line(1), n) :=
|
||||
-1 when n > size(line) - 3 else
|
||||
n when (line[n]=' ' or line[n]='\t') and
|
||||
line[n+1] = '-' and line[n+2] = '>' and
|
||||
(line[n+3]=' ' or line[n+3]='\t') else
|
||||
startOfArrow(line, n+1);
|
||||
|
||||
markov(rules(1), n, input(1)) :=
|
||||
let
|
||||
replaced := replaceSubString(input, rules[n].pattern, rules[n].replacement, 1);
|
||||
in
|
||||
input when n > size(rules) else
|
||||
replaced.newString when replaced.wasReplaced and rules[n].terminal else
|
||||
markov(rules, 1, replaced.newString) when replaced.wasReplaced else
|
||||
markov(rules, n+1, input);
|
||||
|
||||
replaceSubString(str(1), original(1), new(1), n) :=
|
||||
(newString : str, wasReplaced : false)
|
||||
when n > size(str) - size(original) + 1 else
|
||||
(newString : str[1 ... n - 1] ++ new ++ str[n + size(original) ... size(str)], wasReplaced : true)
|
||||
when equalList(str[n ... n + size(original) - 1], original) else
|
||||
replaceSubString(str, original, new, n + 1);
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
fcn parseRuleSet(lines){
|
||||
if(vm.numArgs>1) lines=vm.arglist; // lines or object
|
||||
ks:=L(); vs:=L();
|
||||
foreach line in (lines){
|
||||
if(line[0]=="#") continue; // nuke <comment>
|
||||
pattern,replacement:=line.replace("\t"," ")
|
||||
.split(" -> ",1).apply("strip");
|
||||
ks.append(pattern); vs.append(replacement);
|
||||
}
|
||||
return(ks,vs);
|
||||
}
|
||||
|
||||
fcn markov(text,rules){
|
||||
ks,vs:=rules; eks:=ks.enumerate();
|
||||
do{ go:=False;
|
||||
foreach n,k in (eks){
|
||||
if (Void!=text.find(k)){
|
||||
if (Void==(v:=vs[n])) return(text);
|
||||
if (v[0,1]==".") v=v[1,*] else go=True;
|
||||
text=text.replace(k,v,1);
|
||||
break; // restart after every rule application, unless terminating
|
||||
}
|
||||
}
|
||||
}while(go);
|
||||
text
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
ruleSet:=parseRuleSet("# This rules file is extracted from Wikipedia:",
|
||||
"# 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();
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
parseRuleSet( // rule set in a list
|
||||
T("# Slightly modified from the rules on Wikipedia",
|
||||
"A -> apple", "B -> bag", "S -> .shop", "T -> the",
|
||||
"the shop -> my brother", "a never used -> .terminating rule")) :
|
||||
markov("I bought a B of As from T S.",_).println();
|
||||
|
||||
parseRuleSet("# 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") :
|
||||
markov("I bought a B of As W my Bgage from T S.",_).println();
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
parseRuleSet(File("ruleSet4")) : markov("_1111*11111_",_).println();
|
||||
parseRuleSet(File("ruleSet5")) : markov("000000A000000",_).println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue