#France Pquet-Nadeau
# May 1,2017
# Comparing the results from Touzet and Myers.
# The function of Touzet returns the exact number of words in the neighborhod of a word, whereas the recurrence of Myers gives an upperbound for 
#the condensed-neighborhood of a word. From the recurrences of Myers, we are able to generate a list of words, then remove the repetitions and filter for the prefixes.

import sys
import itertools

from Generating_words_v1 import final_no_repeats, prefixes, Generating_words, repeating_words  # final_no_repeats returns the list of words generated by the recurrences without repetition of words,
                                                                  # prefixes returns the prefixes
                                                                  # These two functions require as input: initial word, distance, empty prefix, Sigma, empty list 1, empty list 2.
from Recurrences_Myer_v1 import upperbound #the upper bound for the number of words  in the condensed neighbourhood
                                                #This function require as input: length of initial word, distance and length of alphbet.
from Recurrence_Touzet_v1 import exact_number_words  #the exact number of words in the neighborhood of a given word


# Parameters reading

Sigma=['a','b'] # initialising the alphabet
s=len(Sigma)    # number of element in the alphabet for upperbound

k = int(sys.argv[1])
d = int(sys.argv[2])
output_file=open(sys.argv[3],"w")



# This function require as input: initial word, Sigma, distance.

def binseq(k):  #constructing all possible words of length k on a given alphabet
    return [''.join(x) for x in itertools.product("".join(Sigma), repeat=k)]  #need to adapt alphabet if not binary.
    
words=binseq(k)  # list of all possible words of length k


pre=''         # initialising prefix, for final_no_repeats and prefixes
start_list=[]   # initialising, for final_no_repeats and prefixes
end_list=[]     # initialising, for final_no_repeats and prefixes

# generating results -------------------------------------------------------------
# exact_number_words, final_no_repeats and prefixes need to be computed for every distinct initial word;
# upperbound only needs to be computed for different length of initial words and  different distances

myers_bound=upperbound(k,d,s)
output_file.write('upper bound Myers '+str(myers_bound)+"\n")

for w in words[0:len(words)/2]:
    output_file.write('word:'+" "+str(w)+" "+'distance:'+" "+str(d)+"\n")
    #output_file.write(w+" "+str(d)+"\n")
    
    touzet=exact_number_words(w,Sigma,d)
    output_file.write('exact neighborhood'+" "+str(touzet)+"\n")
    
    counter,repeat=repeating_words(w,d,pre,Sigma,[],[])
    output_file.write('number of repeats'+" "+str(counter)+"\n")
    output_file.write('words repeated'+" " +", ".join(repr(e) for e in repeat )+"\n")
    
    no_rep=final_no_repeats(w,d,pre,Sigma,[],[])
    output_file.write('bound without repeats'+" "+str(len(no_rep))+"\n")
    
    pref=prefixes(w,d,pre,Sigma,[],[])
    output_file.write('number of prefixes'+" "+str(len(pref))+"\n")
    output_file.write('the prefixes are:'+" " +", ".join(pref)+"\n")
    
output_file.close()
