For those who want to train their tacit muscles, here's a challenge.  A Markov 
algorithm is a specialized term rewriter.  It accepts
a list of rules (denoting substitutions) and a target string to evaluate.  See 
http://rosettacode.org/wiki/Markov_Algorithm  for a
more detailed description, examples, and some implementations (ignore the J 
implementation for now; it is incorrect).

However, the Markov engine has a very strict order of evaluation.  At each 
step, it evaluates the current rule; if the rule matches,
it makes one and only one substitution (to the leftmost match), and then it 
starts over from the beginning (i.e. at rule 0, as
opposed to looking for more matches for this rule or moving on to the next 
rule).  Once all the rules have been applied and no more
matches occur, the (now stable) result is the output of the Markov engine.   
The engine may also termination early, before the
result stabilizes;  a rule may be marked as a "terminator", and if such a rule 
matches, it makes one and only one substitution (to
the leftmost match) and the result is the output of the Markov engine.

Below is a model in explicit J.   Can you rewrite it tacitly?    

Now, the challenge is more than just a tacit rewrite (though that can be a fun 
exercise in itself, especially for those new to tacit
J).  Any stateless explicit code can be rewritten tacitly (Pepe proved this), 
through a fairly mechanical translation procedure.
But the results are often ugly and inferior (longer, harder to read, more 
redundant) than the original explicit model.  For an
example, see 
http://rosettacode.org/wiki/Talk:Markov_Algorithm#explicit_vs_tacit  . 

The challenge truly is:  can you write an elegant tacit Markov algorithm?  

-Dan

------------------

markovLexer  =:  verb define
        rules =.  LF cut TAB&=`(,:&' ')}y
        rules =.  a: -.~ (dltb@:{.~ i:&'#')&.> rules
        rules =.  0 _1 {"1 '\s+->\s+' (rxmatch rxcut ])S:0 rules
 
        NB.  Determine which rules are terminating
        (,. ] (}.&.>~ ,. ]) ('.'={.)&.>)/ |: rules
)
 
 
replace      =:  dyad define
        'index patternLength replacement'=.  x
        'head tail' =.  index split y
 
        head, replacement, patternLength }. tail
)
 
matches      =:  E. i. 1:
 
markovStrict  =:  dyad define
        rules =.  markovLexer x
 
        ruleIdx =. 0
 
        while. ruleIdx < #rules do.
                'pattern replacement terminating' =. ruleIdx { rules
 
                if. (#y) > index =. pattern matches y do.
 
                        y =. (index ; (#pattern) ; replacement) replace y
 
                        if. terminating do.
                        NB.  If terminating rule, just return current string
                                ruleIdx =. #rules 
                        else.
                        NB.  Else reevaluate from the beginning after every 
match
                                ruleIdx =. 0
                        end.
                else.
                        ruleIdx =. 1 + ruleIdx
                end.
        end.
 
        y
)





----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to