1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
/*
** Name: Graftal.h
** Functionality: Adds CRule and CRuleSet classes to simulate regular, stochastic and context sensitive graftal grammars.
** Made by: T. "Kyon" Westendorp
** Example:
CRuleSet graftal;
graftal.add(CRule("1","1","1")>>"1[0]1" // If there is a 1 in between a 1 and a 1, there is a 50% chance it will change into 1[0]1
>>"1"); // If there is a 1 in between a 1 and a 1, there is a 50% chance of not changing
graftal.add(CRule("1")>>"11"); // Change 1 into 11
graftal.add(CRule("0")>>"1[0]0" // 50% chance of changing 0 into 1[0]0
>>"0"); // 50% chance of not changing
std::string x = "0"; // Apply the rules to this axiom
for(unsigned u=0;u<=10;u++) // Evaluate the outcome for the first 10 steps (first printing the axiom)
{
cout << u << " " << x << endl;
graftal.applyrules(x);
}
*/
#ifndef GRAFTAL_H_INCLUDED
#define GRAFTAL_H_INCLUDED
#include <algorithm>
#include <cstdlib>
#include <string>
#include <vector>
#include <list>
struct CRule
{ public:
std::string a;
std::vector<std::string> b;
std::string front;
std::string back;
CRule():a(""),front(""),back("") {}
CRule(std::string A,std::string f="",std::string b=""):a(A),front(f),back(b) {}
CRule(const CRule& r):a(r.a),b(r.b),front(r.front),back(r.back) {}
CRule& operator>>(std::string s);
inline void randomize();};
struct CRuleSet
{ private:
std::list<CRule> rs;
unsigned apply(std::string&,unsigned);
public:
inline void add(CRule);
void applyrules(std::string&);};
CRule& CRule::operator>>(std::string s) {b.push_back(s); return *this;}
void CRule::randomize() {random_shuffle(b.begin(), b.end());}
void CRuleSet::add(CRule r) {rs.push_back(r);}
void CRuleSet::applyrules(std::string& s) {unsigned x=0;while(x<s.size()) x+=apply(s,x);}
unsigned CRuleSet::apply(std::string& s, unsigned i)
{ for(std::list<CRule>::iterator it = rs.begin(); it!=rs.end();it++)
{ if ((it->front==""||(i>=it->front.size()&&it->front==s.substr(i-it->front.size(),it->front.size())))&&it->a==s.substr(i,it->a.size())&&(it->back==""||(i<=s.size()-it->back.size()&&it->back==s.substr(i+it->a.size(),it->back.size()))))
{ it->randomize();
s.erase(i,it->a.size());
s.insert(i,it->b[0]);
return it->b[0].size();}}
return 1;}
#endif // GRAFTAL_H_INCLUDED
|