A (one dimensional) cellular automaton is a function1 F : Σ → Σ with the property that there is a K > 0 such that F (x)i depends only on the 2K + 1 coordinates xi−K , xi−K+1, . . . , xi−1, xi, xi+1, . . . , xi+K . A periodic point of σ is any x such that σ^p (x) = x for some p ∈ N, and a periodic point of F is any x such that F^q (x) = x for some q ∈ N. Given a cellular automaton F, a point x ∈ Σ is jointly periodic if there are p, q ∈ N such that σ^p (x) = F^q (x) = x, that is, it is a periodic point under both functions.
This project aims to explore the nature of one-dimensional Cellular Automata, in the hope of finding the structure of cellular automata through its periodic points.
License: MIT
ubuntu2004
/*1* Copyright (C) 2004 Bryant Lee2*3* This file is part of FDense.4*5* FDense is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* FDense is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with FDense; if not, write to the Free Software17* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA18*/1920/* Main function21* FDense program takes as input N (shift size), k (shift period), the c.a.22* rule f, and m. It determines whether f is m-dense where m-dense means23* that every word of length m appears in a jointly periodic point. If it24* is not m-dense, it lists the words that do not appear in jointly periodic25* points.26*27* Written by: Bryant Lee28* Date: 9/01/0529*/3031#define USEARRAY 032#define DEBUG 03334//Standard C++35#include <string.h>36#include <iostream>37#include <iomanip>38#include <fstream> //for file ops3940//C41#include <stdlib.h> //for atoi42#include <math.h> //for pow4344//STL45#include <vector>46#include <list>47#include <map>4849//local50#include "StringOps.h"51#include "Comp.h"52#include "StorageKey.h"53#include "StorageVal.h"54#include "RecNode.h"5556#include "GroupData.h"57#include "MList.h"5859/*60* Function definitions61*/62void convertPeriodList(const string &strInput, vector<int> &periodList);63void exhaustiveExp(unsigned int shiftSize, const vector<int> &periodList,64unsigned int density, Comp *comp,65list<MList> &recList, MList &unionList, string &prefix,66vector<string> &commandbuffer);67void exhaustiveExpTwoShift(unsigned int shiftSize,68const vector<int> &periodList, unsigned int density,69Comp *comp, list<MList> &recList, MList &unionList,70string &prefix, vector<string> &commandbuffer);71void clearStorageNodes(vector<StorageVal*> &table);72void clearRecList(list<RecNode*> &recList);7374void output(unsigned int shiftSize, int density, string &prefix,75const vector<int> &periodList,76Comp * comp, list<MList> &recList, MList &unionList,77vector<string> &commandbuffer);78void groupoutput(int density, string &prefix, vector<string> &commandbuffer,79vector<GroupData> &groupdata);808182void findDivisors(unsigned int x, vector<int> &divisorsList);8384bool leastPeriod(byte *word, unsigned int currPeriod,85const vector<int> &divisorsList);86bool leastPeriod(unsigned int word, unsigned int currPeriod,87const vector<int> &divisorsList);88void makeMPrefixList(vector<bool> &m_table, MList &record, unsigned int shiftSize);8990/*91* GLOBAL variables92*/93int UINTSIZE = 32;9495int VERBOSE = 0; //display non-appearing m-words for each individual K9697//boolean that determines whether output is given after each completed experiment (after each K)98//or only at end99bool OUTPUT_AFTER_EACH = false;100101//determine whether the output is in the "group" format or the normal format102bool GROUP = false;103104//main105int main() {106//book-keeping variables107unsigned int shiftSize; //# symbols in shift108string prefix; //prefix for output files109string strInput, strInput2, strInput3; //temp variables110string outoption; //output after each or at end111112vector<int> periodList; //list of periods113unsigned int i = 0, temp; //counter114115//results variables116list<MList> recList; //list of prefixes not seen, this is per K value117MList unionList = MList(0); //list of prefixes not seen, over all K values118119//computation variables120Comp *comp = NULL; //composition to apply121unsigned int density;122123//hold the command strings124vector<string> commandbuffer;125int commandbufferit;126127//storage for the "group" option128vector<GroupData> groupdata;129unsigned int groupdatait;130131//grab all input from cin and put in an array of strings132while(!cin.eof()) {133std::getline(cin, strInput);134commandbuffer.push_back(strInput);135}136137commandbufferit = 0;138139//get "output after each" or "output at end"140outoption = commandbuffer[commandbufferit++];141trim(outoption);142transform(outoption.begin(), outoption.end(), outoption.begin(), tolower);143144if(outoption == "output after each") {145OUTPUT_AFTER_EACH = true;146}147else if(outoption == "output at end") {148OUTPUT_AFTER_EACH = false;149}150else {151cout << "Error on line 1: invalid value for output mode\n";152goto cleanup;153}154155//get "group" or "no group"156strInput = commandbuffer[commandbufferit++];157trim(strInput);158transform(strInput.begin(), strInput.end(), strInput.begin(), tolower);159160if(strInput == "group") {161GROUP = true;162}163else if(strInput == "no group") {164GROUP = false;165}166else {167cout << "Error on line 2: invalid value for group mode\n";168goto cleanup;169}170171//get filename prefix172prefix = commandbuffer[commandbufferit++];173trim(prefix);174175//get N, the number of symbols in the full shift176strInput = commandbuffer[commandbufferit++];177trim(strInput);178shiftSize = atoi(strInput.c_str());179180//get set of K, the periodicities to be tested181strInput = commandbuffer[commandbufferit++];182convertPeriodList(strInput, periodList);183184//get m, to check for m-dense185strInput = commandbuffer[commandbufferit++];186trim(strInput);187density = atoi(strInput.c_str());188189//Allocate composition object190comp = new Comp(shiftSize);191192//get "Begin Definitions"193strInput = commandbuffer[commandbufferit++];194195//make it lowercase196trim(strInput);197transform(strInput.begin(), strInput.end(), strInput.begin(), tolower);198199if(strInput.compare("begin definitions") != 0) {200cout << "ERROR: Expecting \"BEGIN DEFINITIONS\"\n";201goto cleanup;202}203204//read definitions205while(1) {206strInput = commandbuffer[commandbufferit++];207208//strInput2 is lowercased and trimmed209strInput2.resize(strInput.length());210transform(strInput.begin(), strInput.end(), strInput2.begin(), tolower);211trim(strInput2);212213//strInput3 is lowercased and NOT TRIMMED214strInput3.resize(strInput.length());215transform(strInput.begin(), strInput.end(), strInput3.begin(), tolower);216217if(strInput2 == "" || (strInput2[0] == '/' && strInput2[1] == '/')) {218//ignore blank lines and allow comment out219}220else if(strInput2 == "begin commands") {221break; //BREAK222}223else {224i = 0;225226while(i < strInput.length()) {227if(strInput[i] == '=') {228break;229}230231i++;232}233234if(strInput2[0] == 'o' && strInput2[1] == 'p' && strInput2[2] == 't') {235temp = strInput3.find("opt");236temp += 3;237238comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)),239strInput.substr(temp, i-temp), true);240}241else {242comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)),243strInput.substr(0,i), false);244}245}246}247248//read all the valid commands and store in groupdata array249while(commandbufferit < (int)commandbuffer.size()) {250strInput = commandbuffer[commandbufferit++];251trim(strInput);252253//ignore blank lines and allow comment out with "//"254if(strInput != "" && !(strInput[0] == '/' && strInput[1] == '/')) {255GroupData gd;256257gd.name = strInput;258groupdata.push_back(gd);259}260}261262//iterate and execute commands263for(groupdatait = 0; groupdatait < groupdata.size(); groupdatait++) {264strInput = groupdata[groupdatait].name;265266//set composition267if(!comp->setComposition(strInput)) {268cout << "ERROR: Command \"" << strInput269<< "\" references undefined function\n";270goto cleanup;271}272273int maxshiftperiod = 0;274for(i = 0; i < periodList.size(); i++)275maxshiftperiod = (maxshiftperiod < periodList[i] ?276periodList[i] : maxshiftperiod);277278//do experiment279if(shiftSize == 2280&& sizeof(unsigned int) == 4281&& !USEARRAY282&& maxshiftperiod <= 32) //if shift period goes > 32 then must use array representation283exhaustiveExpTwoShift(shiftSize, periodList, density, comp, recList,284unionList, prefix, commandbuffer);285else286exhaustiveExp(shiftSize, periodList, density, comp, recList, unionList, prefix, commandbuffer);287288if(!OUTPUT_AFTER_EACH)289output(shiftSize, density, prefix, periodList, comp,290recList, unionList, commandbuffer);291292groupdata[groupdatait].recList = recList;293groupdata[groupdatait].unionList = unionList;294groupdata[groupdatait].pending = false;295296//clear list of prefixes297recList.clear();298299if(OUTPUT_AFTER_EACH) {300groupoutput(density, prefix, commandbuffer, groupdata);301}302}303304//Do the group output (assuming output at end)305if(!OUTPUT_AFTER_EACH) {306groupoutput(density, prefix, commandbuffer, groupdata);307}308309//cleanup and exit310cleanup:311312//delete composition (and the functions in the Comp object's storage)313delete comp;314315return 0;316}317318/*319* Group output320*/321322void groupoutput(int density, string &prefix, vector<string> &commandbuffer,323vector<GroupData> &groupdata) {324int commandbufferit;325int groupdatait;326327if(GROUP) {328ofstream fout;329string fname = prefix + "group.txt";330fout.open(fname.c_str(), ios::trunc | ios::out);331332if(!fout.is_open()) {333cout << "ERROR: could not create file " << fname << "\n";334}335336fout << "FDense 3.67\n\n";337338//copy of the input339fout << "INPUT\n";340fout << "--------------------\n";341for(commandbufferit = 0; commandbufferit < (int)commandbuffer.size(); commandbufferit++) {342string test;343test = commandbuffer[commandbufferit];344trim(test);345if(test != "") {346fout << commandbuffer[commandbufferit] << "\n";347}348}349fout << "--------------------\n";350fout << "\n";351352fout << "For m = " << density << " the following maps were found to have m-dense jointly periodic points of (not least) shift period k, "353<< "for the following k:" << "\n";354fout << "\n";355356for(groupdatait = 0; groupdatait < (int)groupdata.size(); groupdatait++) {357bool none = true;358359fout << "Map: " << groupdata[groupdatait].name << "\n";360fout << "----" << "\n";361362if(groupdata[groupdatait].pending) {363fout << "PENDING" << "\n";364}365else {366list<MList>::const_iterator it;367for(it = groupdata[groupdatait].recList.begin(); it != groupdata[groupdatait].recList.end(); it++) {368if((*(it->List.begin())).compare("m-dense") == 0) {369fout << it->currPeriod << "\n";370none = false;371}372}373374if(none) {375fout << "none" << "\n";376}377}378379fout << "\n";380}381382fout.close();383}384}385386387/*388* Full output389*/390391void output(unsigned int shiftSize, int density, string &prefix,392const vector<int> &periodList, Comp * comp, list<MList> &recList,393MList &unionList, vector<string> &commandbuffer) {394list<MList>::const_iterator it;395//unsigned int i;396unsigned int commandbufferit;397398if(!GROUP) {399400//output401ofstream fout;402string fname = prefix + comp->returnName() + ".txt";403fout.open(fname.c_str(), ios::trunc | ios::out);404405if(!fout.is_open()) {406cout << "ERROR: could not create file " << fname << "\n";407return;408}409410//HEADER411fout << "FDense 3.67\n";412413/*414fout << "N = " << shiftSize << "\n";415fout << "K = ";416for(i = 0; i < periodList.size(); i++) {417fout << periodList[i];418if(i != periodList.size() - 1)419fout << ",";420}421fout << "\n";422fout << "m = " << density;423fout << "\n";424*/425426fout << "\n";427428//copy of the input429fout << "INPUT\n";430fout << "--------------------\n";431for(commandbufferit = 0; commandbufferit < commandbuffer.size(); commandbufferit++) {432string test;433test = commandbuffer[commandbufferit];434trim(test);435if(test != "") {436fout << commandbuffer[commandbufferit] << "\n";437}438}439fout << "--------------------\n";440fout << "\n";441442//fill on right side, show in fixed notation443fout << setiosflags(ios::left | ios::fixed);444445fout << "COMMAND:\n";446fout << comp->returnName() << "\n";447fout << "WITH DEFINITIONS:\n";448comp->printDefinitions(fout);449fout << "\n";450451fout << "Outcomes Summary\n";452for(it = recList.begin(); it != recList.end(); it++) {453fout << "K=" << it->currPeriod << " ";454if(it->pending) {455fout << "PENDING";456}457else {458if((*(it->List.begin())).compare("m-dense") == 0) {459fout << "m-dense";460}461else {462fout << "not m-dense";463}464}465fout << "\n";466}467fout << "\n";468469fout << "List of m-words not appearing in jointly periodic points\n\n";470471fout << "For union of all K (excluding those that are PENDING)\n\n";472list<string>::const_iterator subit;473for(subit = unionList.List.begin(); subit != unionList.List.end(); subit++) {474fout << *subit << "\n";475}476fout << "\n";477478if(VERBOSE) {479fout << "For each particular value of K\n\n";480481for(it = recList.begin(); it != recList.end(); it++) {482fout << "K = " << it->currPeriod << "\n";483484if(it->pending) {485fout << "PENDING" << "\n";486fout << "\n";487}488else {489for(subit = it->List.begin(); subit != it->List.end(); subit++) {490fout << *subit << "\n";491}492fout << "\n";493}494}495}496497//DONE498fout.close();499}500}501502void exhaustiveExp(unsigned int shiftSize, const vector<int> &periodList,503unsigned int density, Comp *comp,504list<MList> &recList, MList &unionList, string &prefix,505vector<string> &commandbuffer) {506unsigned int i = 0, j = 0; //k = 0; //counters507unsigned int currPeriod;508509list<StorageKey> orbitList;510list<StorageKey> periodicPoints;511512vector<int> table; //table for storing points, checking for intersections513vector<bool> global_m_table(pow(shiftSize,density), false); //table for storing m-words not found in union over all K514515list<MList>::iterator recIterator;516517if(DEBUG)518cout << "Arrays\n";519520//make a list of MList nodes, one per K value521for(i = 0; i < periodList.size(); i++) {522recList.push_back(MList(periodList[i]));523}524525//initialize recIterator526recIterator = recList.begin();527528for(i = 0; i < periodList.size(); i++) {529currPeriod = periodList[i];530byte itWord[currPeriod]; //iterating word531532MList *record = &(*recIterator);533534if(DEBUG)535cout << "currPeriod = " << currPeriod << "\n";536537//set table size538table.resize(pow(shiftSize,currPeriod), -2); //initialize to -2539540if(DEBUG)541cout << "Allocated table\n";542543//zero the itWord544for(j = 0; j < currPeriod; j++) {545itWord[j] = 0;546}547548while(true) {549byte cWord[currPeriod]; //curr word550byte output[currPeriod]; //helper word551unsigned int period = 0, preperiod = 0;552int rt;553bool halt = false;554555while(halt != true &&556table[StorageKey(itWord,currPeriod).hash(shiftSize)] != -2)557{558halt = iterateWord(itWord, currPeriod, shiftSize);559}560561if(halt == true)562break; //exit loop563564//Set current word565copyWord(cWord, itWord, currPeriod);566567StorageKey sk1 = StorageKey(cWord, currPeriod);568569table[sk1.hash(shiftSize)] = 0;570571orbitList.push_back(sk1);572573//DEBUG574//cout << "\n-- Start orbit --\n";575//printArray(cWord, currPeriod);576577//Perform experiment578j = 1;579while(true) {580comp->image(cWord, currPeriod, output);581copyWord(cWord, output, currPeriod);582583//DEBUG584//printArray(cWord, currPeriod);585586StorageKey sk2 = StorageKey(cWord, currPeriod);587588rt = table[sk2.hash(shiftSize)];589if(rt != -2) {590break;591}592else {593table[sk2.hash(shiftSize)] = j;594orbitList.push_back(sk2);595}596597j++;598}599600if(rt == -1) {601//returned to a point we've seen602//none of these points can be periodic603604list<StorageKey>::iterator it;605for(it = orbitList.begin(); it != orbitList.end(); it++) {606table[it->hash(shiftSize)] = -1;607}608}609else {610//we circled back to an active point611period = j - rt;612preperiod = rt;613614list<StorageKey>::iterator it;615for(it = orbitList.begin(); it != orbitList.end(); it++) {616table[it->hash(shiftSize)] = -1; //mark as seen617618if(preperiod > 0) {619preperiod--;620}621else {622periodicPoints.push_back(*it);623}624}625}626627//cout << "Clearing list\n";628orbitList.clear();629}630631//cout << "Clearing table\n";632table.clear();633634//DEBUG635/*636{637cout << "\n\nPeriodic points\n";638list<StorageKey>::iterator it;639for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) {640printArray(it->word, currPeriod);641}642}643*/644//DEBUG645646//DEBUG: make a fake point for testing647/*648periodicPoints.clear();649byte t_arr[7];650t_arr[0] = 1;651t_arr[1] = 2;652t_arr[2] = 0;653t_arr[3] = 1;654t_arr[4] = 1;655t_arr[5] = 1;656t_arr[6] = 1;657periodicPoints.push_back(StorageKey(t_arr, 7));658*/659//DEBUG660661//now cross off all m_words that do not exist in periodic point662663vector<bool> m_table(pow(shiftSize,density), false); //table of all m_words (for this particular K)664byte m_word[density];665StorageKey hasher(m_word, density);666unsigned int location;667668list<StorageKey>::iterator it;669for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) {670671for(location = 0; location < currPeriod; location++) {672673//read the word674for(j = 0; j < density; j++) {675hasher.word[j] = it->word[(j + location) % currPeriod];676}677678//MAKE SURE TO USE hash_baseB SO THEY HASH TO THE RIGHT PLACE679m_table[hasher.hash_baseB(shiftSize)] = true; //for this particular K680global_m_table[hasher.hash_baseB(shiftSize)] = true; //for all K681}682}683684makeMPrefixList(m_table, (*record), shiftSize);685686unionList.List.clear(); //clear the list, it will be reset from the complete global table that has all the info687makeMPrefixList(global_m_table, unionList, shiftSize);688689//clear periodicpoints list690periodicPoints.clear();691692record->pending = false;693694//advance recIterator to next in list695recIterator++;696697if(OUTPUT_AFTER_EACH) {698output(shiftSize, density, prefix, periodList, comp, recList, unionList,699commandbuffer);700}701}702}703704void makeMPrefixList(vector<bool> &m_table, MList &record, unsigned int shiftSize) {705unsigned int j; //counter706707//DEBUG: make a fake table for testing708/*709for(j = 0; j < m_table.size(); j++)710m_table[j] = false;711712for(j = 0; j <= 1; j++) {713m_table[j] = true;714}715for(j = 12; j <= 27; j++) {716m_table[j] = true;717}718for(j = 52; j < m_table.size(); j++) {719m_table[j] = true;720}721*/722//DEBUG723724//DEBUG: print the m_table725/*726cout <<"\n\nm_table\n";727for(j = 0; j < m_table.size(); j++) {728if(m_table[j]) {729unsigned int t;730for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) {731cout << (j / t) % shiftSize;732if(t > 1)733cout << ",";734}735cout << "\n";736}737}738*/739//DEBUG740741//now list the m words lexicographically with truncate742unsigned int count_true = 0; //count true's, lets us know if table full743for(j = 0; j < m_table.size(); j++) {744if(!m_table[j]) {745string m_prefix = "";746747if(j % shiftSize == 0) { //has a zero at lsb so this might be cut to a prefix748//t = shiftSize ^ (numzeros on right in j in base shiftsize)749unsigned int t;750for(t = shiftSize; (j / t) % shiftSize == 0751&& t < m_table.size(); t *= shiftSize) {752}753754//count is how many adjacent elements are false (counting this one)755unsigned int count;756for(count = 1; count < t && !m_table[j + count]; count++) {757}758759//s is the largest power of shiftsize that is <= count760unsigned int s;761for(s = shiftSize; s <= count; s *= shiftSize) {762}763s /= shiftSize; //adjust since the for loop goes 1 further764765int spacing = 0; //count up to four, then add a space766767//create the correct prefix768for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) {769char temp_c[80];770771if(t >= s) {772sprintf(temp_c, "%d", (j / t) % shiftSize);773m_prefix += string(temp_c);774}775else776m_prefix += "-";777778if(spacing % 4 == 3) //on every fourth char, add a space779m_prefix += " ";780781spacing++;782}783784// j JUMPS s SPACES AHEAD because these s elements constitute785// one prefix, but at the end of the loop j increments 1 more,786// so we need to increment by s - 1787j += (s - 1);788789}790else { //not a prefix791unsigned int t;792793int spacing = 0;794795for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) {796char temp_c[80];797798sprintf(temp_c, "%d", (j / t) % shiftSize);799m_prefix += string(temp_c);800801if(spacing % 4 == 3)802m_prefix += " ";803804spacing++;805}806}807808//push back a prefix of non-appearing word809record.List.push_back(m_prefix);810}811else {812count_true++;813814//push back m-dense815if(count_true == m_table.size()) {816record.List.push_back("m-dense");817}818}819}820}821822void exhaustiveExpTwoShift(unsigned int shiftSize,823const vector<int> &periodList,824unsigned int density,825Comp *comp, list<MList> &recList, MList &unionList,826string &prefix, vector<string> &commandbuffer) {827unsigned int i = 0, j = 0; //k = 0; //counters828unsigned int currPeriod, numTrials;829830list<unsigned int> orbitList;831list<unsigned int> periodicPoints;832833vector<int> table; //table for storing points, checking for intersections834vector<bool> global_m_table(pow(shiftSize,density), false); //table for storing m-words not found in union over all K835836list<MList>::iterator recIterator;837838if(DEBUG)839cout << "Special case 2-shift\n";840841//make a list of MList nodes, one per K value842for(i = 0; i < periodList.size(); i++) {843recList.push_back(MList(periodList[i]));844}845846//initialize recIterator847recIterator = recList.begin();848849for(i = 0; i < periodList.size(); i++) {850currPeriod = periodList[i];851unsigned int itWord = 0; //iterating word852853MList *record = &(*recIterator);854855numTrials = (int) pow(2, currPeriod);856857table.resize(numTrials, -2);858859while(true) {860unsigned int cWord = 0; //curr word861unsigned int output = 0; //helper word862unsigned int period = 0, preperiod = 0;863int rt;864865while(itWord != numTrials &&866table[itWord] != -2) {867itWord++;868}869870if(itWord == numTrials)871break; //exit loop872873//Set current word874cWord = itWord;875876table[cWord] = 0;877orbitList.push_back(cWord);878879//DEBUG880//cout << "-- start orbit --\n";881//printUInt(cWord, currPeriod);882883//Perform experiment884j = 1;885while(true) {886comp->image(&cWord, currPeriod, &output, 1);887888cWord = output;889890//DEBUG891//printUInt(cWord, currPeriod);892893rt = table[cWord];894if(rt != -2) {895break;896}897else {898table[cWord] = j;899orbitList.push_back(cWord);900}901902j++;903}904905//DEBUG906//cout << "-- end orbit --\n";907908if(rt == -1) {909//returned to a point we've seen910//none of these points can be periodic911912list<unsigned int>::iterator it;913for(it = orbitList.begin(); it != orbitList.end(); it++) {914table[*it] = -1;915}916}917else {918//we circled back to an active point919period = j - rt;920preperiod = rt;921922list<unsigned int>::iterator it;923for(it = orbitList.begin(); it != orbitList.end(); it++) {924table[*it] = -1;925926if(preperiod > 0) {927preperiod--;928}929else {930periodicPoints.push_back(*it);931}932}933}934935//cout << "Clearing list\n";936orbitList.clear();937}938939//cout << "Clearing table\n";940table.clear();941942//DEBUG943/*944{945cout << "\n\nPeriodic points\n";946list<unsigned int>::iterator it;947for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) {948printUInt(*it, currPeriod);949}950}951*/952//DEBUG953954//DEBUG: make up the periodicpoint955/*956periodicPoints.clear();957periodicPoints.push_back(23);958*/959//DEBUG960961//now cross off all m_words that exist in periodic point962963vector<bool> m_table(pow(2,density), false); //table of all m_words964byte m_word[density];965StorageKey hasher(m_word, density);966unsigned int location;967968list<unsigned int>::iterator it;969for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) {970971for(location = 0; location < currPeriod; location++) {972973//read the word974for(j = 0; j < density; j++) {975int index = (j + location) % currPeriod;976977hasher.word[j] = (*it & (1 << index)) >> index;978}979980//MAKE SURE TO USE hash_baseB SO THEY HASH TO THE RIGHT PLACE981m_table[hasher.hash_baseB(2)] = true; //for this K982global_m_table[hasher.hash_baseB(2)] = true; //for union of K983}984}985986makeMPrefixList(m_table, (*record), shiftSize);987988unionList.List.clear(); //clear the list, it will be reset from the complete global table that has all the info989makeMPrefixList(global_m_table, unionList, shiftSize);990991//clear periodicPoints992periodicPoints.clear();993994record->pending = false;995//advance recIterator to next in list996recIterator++;997998if(OUTPUT_AFTER_EACH) {999output(shiftSize, density, prefix, periodList, comp, recList, unionList,1000commandbuffer);1001}1002}1003}10041005void convertPeriodList(const string &strInput,1006vector<int> &periodList) {1007vector<string> strList; //all terms1008vector<string> subList; //vector representation of an "[a,b]" term1009unsigned int strListLength = 0, i = 0;10101011split(strInput,';', strList);1012strListLength = strList.size();10131014for(i = 0; i < strListLength; i++) {1015string *temp = &(strList[i]);10161017trim(*temp);10181019if((*temp)[0] == '[') {1020int j, low, high;10211022temp->erase(0,1); //remove '['1023temp->erase(temp->length() - 1, 1); //remove ']'10241025split(*temp, ',', subList);10261027trim(subList[0]);1028trim(subList[1]);10291030low = atoi(subList[0].c_str());1031high = atoi(subList[1].c_str());10321033for(j = low; j <= high; j++) {1034periodList.push_back(j);1035}10361037subList.clear();1038}1039else {1040periodList.push_back(atoi(temp->c_str()));1041}1042}1043}10441045/*1046* Delete the nodes pointed to by ptrs in recList1047*/1048void clearRecList(list<RecNode*> &recList) {1049list<RecNode*>::iterator it;10501051for(it = recList.begin(); it != recList.end(); it++) {1052delete (*it);1053}1054}10551056/*1057* Delete the nodes pointed to by the values in the table1058*/1059void clearStorageNodes(vector<StorageVal*> &table) {1060vector<StorageVal*>::iterator it;10611062for(it = table.begin(); it != table.end(); it++) {1063delete (*it);1064}1065}10661067/*1068* Find divisors of X, excluding X itself1069*/1070void findDivisors(unsigned int x, vector<int> &divisorsList) {1071unsigned int i = 2;1072unsigned int halfX = x/2;10731074divisorsList.clear();10751076if(x > 1) {1077divisorsList.push_back(1);1078}10791080for(i = 2; i <= halfX; i++) {1081if(x % i == 0) {1082divisorsList.push_back(i);1083}1084}1085}10861087/*1088* returns true if this word has least period p1089*/1090bool leastPeriod(byte *word, unsigned int currPeriod,1091const vector<int> &divisorsList) {1092bool result = false;1093unsigned int i, j, k;10941095if(currPeriod == 1)1096return true;10971098//for every divisor d1099for(i = 0; i < divisorsList.size(); i++) {1100unsigned int d = divisorsList[i];11011102result = false;11031104//check in chunks of length d1105for(j = 0; j < currPeriod; j+= d) {1106//check that this chunk is same as other chunks1107for(k = 0; k < d; k++) {1108if(word[k + j] != word[k]) {1109result = true;1110break;1111}1112}11131114if(result == true)1115break;1116}11171118if(result == false)1119break;1120}11211122return result;1123}11241125/*1126* returns true if this word has least period p1127*/1128bool leastPeriod(unsigned int word, unsigned int currPeriod,1129const vector<int> &divisorsList) {1130bool result = false;1131unsigned int i, j, k;11321133if(currPeriod == 1)1134return true;11351136//for every divisor d1137for(i = 0; i < divisorsList.size(); i++) {1138unsigned int d = divisorsList[i];11391140result = false;11411142//check in chunks of length d1143for(j = 0; j < currPeriod; j+= d) {1144//check that this chunk is same as other chunks1145for(k = 0; k < d; k++) {1146if(((word >> (k + j)) & 1) != ((word >> k) & 1)) {1147result = true;1148break;1149}1150}11511152if(result == true)1153break;1154}11551156if(result == false)1157break;1158}11591160return result;1161}116211631164116511661167116811691170117111721173117411751176117711781179