diff --git a/BDD pavlos/BDDs/.idea/BDDs.iml b/BDD pavlos/BDDs/.idea/BDDs.iml
new file mode 100644
index 0000000..85c7612
--- /dev/null
+++ b/BDD pavlos/BDDs/.idea/BDDs.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BDD pavlos/BDDs/.idea/misc.xml b/BDD pavlos/BDDs/.idea/misc.xml
new file mode 100644
index 0000000..9b40031
--- /dev/null
+++ b/BDD pavlos/BDDs/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/BDD pavlos/BDDs/.idea/modules.xml b/BDD pavlos/BDDs/.idea/modules.xml
new file mode 100644
index 0000000..a72c047
--- /dev/null
+++ b/BDD pavlos/BDDs/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BDD pavlos/BDDs/.idea/workspace.xml b/BDD pavlos/BDDs/.idea/workspace.xml
new file mode 100644
index 0000000..c02660d
--- /dev/null
+++ b/BDD pavlos/BDDs/.idea/workspace.xml
@@ -0,0 +1,704 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1530598575334
+
+
+ 1530598575334
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BDD pavlos/BDDs/bdd_graph.png b/BDD pavlos/BDDs/bdd_graph.png
new file mode 100644
index 0000000..4829b13
Binary files /dev/null and b/BDD pavlos/BDDs/bdd_graph.png differ
diff --git a/BDD pavlos/BDDs/bdd_seq_logic.py b/BDD pavlos/BDDs/bdd_seq_logic.py
new file mode 100644
index 0000000..8fc101b
--- /dev/null
+++ b/BDD pavlos/BDDs/bdd_seq_logic.py
@@ -0,0 +1,68 @@
+import test_simplify
+
+# string is function
+# seq is a list of variables sequence
+# creates the functions of each BDD node and gives the final binaries of each unsimplified BDD node
+
+
+def build(seq, string):
+
+ # write sequence to .txt file
+ text = ""
+ for i in range(len(seq)):
+ var = str(seq[i]) + "\n"
+ text += var
+ f = open('sequence.txt', 'w')
+
+ f.write(text)
+ f.close()
+
+ function_collection = list()
+
+ func_list = list()
+
+ # first element that cannot be edited in loop
+ function_collection.append(string)
+
+ branch = 1
+
+ for i in range(1, len(seq) + 1):
+
+ branch *= 2
+
+ for j in range(branch):
+
+ if branch == 2:
+ if j == 0:
+ func_list.append(test_simplify.build_0(function_collection[0], seq[i-1]))
+ elif j == 1:
+ func_list.append(test_simplify.build_1(function_collection[0], seq[i-1]))
+ else:
+ index = int(j/2)
+ if j % 2 == 0:
+ func_list.append(test_simplify.build_0(function_collection[i-1][index], seq[i-1]))
+ elif j % 2 != 0:
+ func_list.append(test_simplify.build_1(function_collection[i-1][index], seq[i-1]))
+
+ function_collection.append(func_list)
+ func_list = []
+
+ return function_collection
+
+
+# returns only the final results (0s and 1s) of each branch
+# NOT SIMPLIFIED
+def get_func_results(func_col):
+
+ final_result = func_col[len(func_col) - 1]
+
+ text = ""
+ f = open('binary_results.txt', 'w')
+
+ for i in range(len(final_result)):
+ text += str(final_result[i]) + "\n"
+
+ f.write(text)
+ f.close()
+
+ return final_result
diff --git a/BDD pavlos/BDDs/bdd_simplification.py b/BDD pavlos/BDDs/bdd_simplification.py
new file mode 100644
index 0000000..595fe16
--- /dev/null
+++ b/BDD pavlos/BDDs/bdd_simplification.py
@@ -0,0 +1,6 @@
+import bdd_seq_logic
+
+
+def simplify_bdd(seq, string):
+
+ bdd_seq_logic.build(seq, string)
diff --git a/BDD pavlos/BDDs/binary_results.txt b/BDD pavlos/BDDs/binary_results.txt
new file mode 100644
index 0000000..6657c6c
--- /dev/null
+++ b/BDD pavlos/BDDs/binary_results.txt
@@ -0,0 +1,16 @@
+0
+1
+1
+1
+0
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
diff --git a/BDD pavlos/BDDs/data.txt b/BDD pavlos/BDDs/data.txt
new file mode 100644
index 0000000..26c8ec3
--- /dev/null
+++ b/BDD pavlos/BDDs/data.txt
@@ -0,0 +1,4 @@
+new_seq['a', 'b1', 'b2', 'c1', 'c2', 'c3', 'c4', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8']
+pos{'a': (100, 100), 'b1': (50.0, 66.66666666666666), 'b2': (150.0, 66.66666666666666), 'c1': (15.0, 33.33333333333332), 'c2': (75.0, 33.33333333333332), 'c3': (65.0, 33.33333333333332), 'c4': (225.0, 33.33333333333332), 'd1': (-12.5, -1.4210854715202004e-14), 'd2': (22.5, -1.4210854715202004e-14), 'd3': (17.5, -1.4210854715202004e-14), 'd4': (112.5, -1.4210854715202004e-14), 'd5': (12.5, -1.4210854715202004e-14), 'd6': (97.5, -1.4210854715202004e-14), 'd7': (92.5, -1.4210854715202004e-14), 'd8': (337.5, -1.4210854715202004e-14), '0': (95, -100.00000000000001), '1': (105, -100.00000000000001)}
+edges_list[('a', 'b1'), ('a', 'b2'), ('b1', 'c1'), ('b1', 'c2'), ('b2', 'c3'), ('b2', 'c4'), ('c1', 'd1'), ('c1', 'd2'), ('c2', 'd3'), ('c2', 'd4'), ('c3', 'd5'), ('c3', 'd6'), ('c4', 'd7'), ('c4', 'd8'), ('d1', '1'), ('d1', '0'), ('d2', '1'), ('d2', '1'), ('d3', '1'), ('d3', '0'), ('d4', '1'), ('d4', '1'), ('d5', '1'), ('d5', '0'), ('d6', '1'), ('d6', '1'), ('d7', '1'), ('d7', '1'), ('d8', '1'), ('d8', '1')]
+labels{('a', 'b1'): '0', ('a', 'b2'): '1', ('b1', 'c1'): '0', ('b1', 'c2'): '1', ('b2', 'c3'): '0', ('b2', 'c4'): '1', ('c1', 'd1'): '0', ('c1', 'd2'): '1', ('c2', 'd3'): '0', ('c2', 'd4'): '1', ('c3', 'd5'): '0', ('c3', 'd6'): '1', ('c4', 'd7'): '0', ('c4', 'd8'): '1', ('d1', '1'): '0', ('d1', '0'): '1', ('d2', '1'): '1', ('d3', '1'): '0', ('d3', '0'): '1', ('d4', '1'): '1', ('d5', '1'): '0', ('d5', '0'): '1', ('d6', '1'): '1', ('d7', '1'): '1', ('d8', '1'): '1'}
diff --git a/BDD pavlos/BDDs/graph.py b/BDD pavlos/BDDs/graph.py
new file mode 100644
index 0000000..1017a9a
--- /dev/null
+++ b/BDD pavlos/BDDs/graph.py
@@ -0,0 +1,226 @@
+import matplotlib.pyplot as plt
+import networkx as nx
+import bdd_seq_logic as bdd
+
+
+# NEED TO TWEAK THE POSITIONING X ALGORITHM SO THAT THE NODES DO NOT FALL ONTO EACHOTHER
+
+# generates a list of final binaries
+def create_final_bin_list(seq, string):
+
+ graph_list = list()
+
+ graph_list.append(([seq[0]]))
+ for i in range(1, len(seq)):
+ graph_list.append([seq[i], seq[i]])
+
+ graph_list.append(bdd.get_func_results(bdd.build(seq, string)))
+
+ results = graph_list[len(graph_list) - 1]
+
+ # if you were to create a full tuple list for edges if the BDD was simplified
+ # final_graph_list = list()
+ # create list without final binaries
+ # branch = 1
+ # for i in range(len(seq) - 1):
+ #
+ # branch *= 2
+ #
+ # for j in range(branch):
+ # final_graph_list.append(tuple([seq[i], seq[i + 1]]))
+
+ # add final binaries to final_graph_list
+ # for i in range(len(results)):
+ # final_graph_list.append(tuple([seq[len(seq) - 1], results[i]]))
+ # NEED TO ADD NUMBERS TO EACH VARIABLE WITH str(variable) + str(number)
+ # SO THAT THE GRAPH RECOGNISES IT
+ # final_graph_list is the final list with tuples to represent the edges of the graph
+
+ return results
+
+
+# not simplified
+# used for graph
+def create_new_seq(seq):
+
+ # create new seq list that gives indexes to variables( [a, b, c] would be [a, b1, b2, c1, c2, c3, c4])
+ new_seq = list()
+ new_seq.append(seq[0])
+
+ branch = 1
+ for i in range(1, len(seq)):
+ branch *= 2
+ for j in range(branch):
+ new_seq.append(seq[i] + str(j + 1))
+
+ # new_seq is used as nodes list for nx graph
+ return new_seq
+
+
+# create edges tuples
+# need to modify generate_graph to work with new_seq
+def create_edges(seq, new_seq, string):
+ # make it check indexes and variable names to avoid confusion
+ # matches all variables with indexes from new_seq to final binaries in initial seq
+ # branches is the number that represents how many variables with the same name(but different index) exist
+ # that helps with matching the binaries
+ branches = 1
+ for i in range(len(new_seq)-1, 1, -1):
+
+ if str(new_seq[i][0]) != str(new_seq[i-1][0]):
+ break
+ else:
+ branches += 1
+
+ # 'c1', 'c2', 'c3', 'c4' --> '0', '1', '0', '1', '0', '1', '1', '1'
+ # need to create a new_results list of tuples to create the new edges
+ results = create_final_bin_list(seq, string)
+
+ # this loop creates the list of tuples that will be used as edges
+ edge_list = list()
+
+ for i in range(len(new_seq) - branches):
+ for j in range(2*i + 1, 2*i + 3):
+ edge_list.append(tuple([new_seq[i], new_seq[j]]))
+
+ # need to add binaries to final (branches(number of tuples)) variables
+ for i in range(len(new_seq) - branches, len(new_seq)):
+ for j in range(2*(i-branches) + 1, 2*(i-branches) + 3):
+ edge_list.append(tuple([new_seq[i], results[j]]))
+
+ return edge_list
+
+
+# print("\n")
+# print(create_edges(["a", "b", "c", "d"], create_new_seq(["a", "b", "c", "d"]), "ab + c + d"))
+
+
+def create_positioning(seq):
+
+ new_seq = create_new_seq(seq)
+ pos = {}
+
+ list_x = list()
+ list_y = list()
+
+ # for list y
+ y = 100
+ dec_y = 100/3
+ list_y.append(y)
+ for i in range(len(seq) - 1):
+ y -= dec_y
+ list_y.append(y)
+
+ # for list x
+ list_x.append(100)
+ branch = 1
+ temp = list()
+ list_x.append([list_x[0] - (list_x[0]/2), list_x[0] + (list_x[0]/2)])
+
+ # middle nodes are placed onto each other
+ for i in range(1, len(seq)):
+ branch *= 2
+ for j in range(branch):
+ temp.append(list_x[i][j] - 10)
+ temp.append(list_x[i][j] + 10)
+
+ list_x.append(temp)
+ temp = []
+
+ # pos.update({...: ...}) appends to dictionary
+ # create pos
+ pos.update({str(new_seq[0]): tuple([str(list_x[0]), str(list_y[0])])})
+
+ branch = 1
+ coord = [(int(100), int(100))]
+ for i in range(1, len(seq)):
+ y = list_y[i]
+
+ branch *= 2
+ for j in range(branch):
+
+ x = list_x[i][j]
+
+ coord.append(tuple([x, y]))
+
+ for i in range(1, len(new_seq)):
+ pos.update({str(new_seq[i]): coord[i]})
+
+ # need to add binaries positions
+ pos.update({"0": (95, list_y[len(list_y)-1] - 100),
+ "1": (105, list_y[len(list_y)-1] - 100)
+ })
+
+ pos["a"] = (100, 100)
+
+ return pos
+
+
+def create_labels(edge_list):
+
+ labels = dict()
+
+ for i in range(len(edge_list)):
+ if i % 2 == 0:
+ labels.update({edge_list[i]: '0'})
+ elif i % 2 != 0:
+ labels.update({edge_list[i]: '1'})
+
+ return labels
+
+
+# GUI NEEDS TO CALL ONLY THIS FUNCTION AFTER IMPORTING JUST THIS MODULE
+
+# seq is a list of the variables sequence
+# string is the function
+# both parameters are given by the user
+def generate_graph(seq, string):
+
+ g = nx.DiGraph()
+
+ new_seq = create_new_seq(seq)
+ g.add_nodes_from(new_seq)
+
+ pos = create_positioning(seq)
+
+ edges_list = create_edges(seq, new_seq, string)
+
+ labels = create_labels(edges_list)
+
+ # save data to file
+ file = open('data.txt', 'w')
+ text1 = str(new_seq)
+ text2 = str(pos)
+ text3 = str(edges_list)
+ text4 = str(labels)
+ line_feed = "\n"
+ file.write("new_seq")
+ file.write(text1)
+ file.write(line_feed)
+ file.write("pos")
+ file.write(text2)
+ file.write(line_feed)
+ file.write("edges_list")
+ file.write(text3)
+ file.write(line_feed)
+ file.write("labels")
+ file.write(text4)
+ file.write(line_feed)
+
+ file.close()
+
+ # make graph
+ g.add_edges_from(edges_list)
+
+ edge_labels = nx.draw_networkx_edge_labels(g, pos, labels)
+ # DOES NOT WORK BECAUSE OF MODULE ERROR
+ nx.draw(g, pos, with_labels=True)
+ # DOESN'T WORK WITH THIS POS....gives ERROR from the module not my program
+ # nx.draw_circular(g, with_labels=True)
+ plt.savefig('bdd_graph.png')
+ # plt.show()
+ # does not save as .jpg
+
+
+generate_graph(["a", "b", "c", "d"], "ab + c + d")
+
diff --git a/BDD pavlos/BDDs/sequence.txt b/BDD pavlos/BDDs/sequence.txt
new file mode 100644
index 0000000..d68dd40
--- /dev/null
+++ b/BDD pavlos/BDDs/sequence.txt
@@ -0,0 +1,4 @@
+a
+b
+c
+d
diff --git a/BDD pavlos/BDDs/simplify.py b/BDD pavlos/BDDs/simplify.py
new file mode 100644
index 0000000..9bf53d5
--- /dev/null
+++ b/BDD pavlos/BDDs/simplify.py
@@ -0,0 +1,199 @@
+# functions for basic simplification of a boolean function
+
+
+def simplify_0(string):
+
+ string = string.replace(' + ', '_')
+ s = string.split('_')
+
+ for i in range(len(s)):
+ if '0' in s[i]:
+
+ # changed it from remove the element(s.remove(s[i])) to replacing it with 0
+ s[i] = "0"
+
+ for i in range(len(s)):
+ s[i] += " + "
+
+ index = len(s) - 1
+ s[index] = s[index].replace(" + ", "")
+
+ string = "".join(s)
+
+ return string
+
+
+def simplify_1(string):
+
+ s = string.split(' + ')
+
+ for i in range(len(s)):
+ if s[i] == "1":
+ string = "1"
+ return string
+
+ for i in range(len(s)):
+ s[i] = s[i].replace('1', '')
+
+ for i in range(len(s)):
+ s[i] += " + "
+
+ index = len(s) - 1
+ s[index] = s[index].replace(" + ", "")
+ string = "".join(s)
+
+ return string
+
+
+def replace_complement(string):
+ s = string.split(' + ')
+
+ for i in range(len(s)):
+ if "'" in s[i]:
+ hold = list(s[i])
+
+ for j in range(len(hold)):
+ if hold[j] == "'":
+ hold[j] = ""
+ hold[j - 1] = hold[j - 1].upper()
+
+ s[i] = "".join(hold)
+
+ for i in range(len(s) - 1):
+ if i != len(s):
+ s[i] += " + "
+
+ string = "".join(s)
+
+ return string
+
+
+def same_var_or(string):
+
+ s = string.split(' + ')
+
+ for i in range(len(s) - 1):
+ count = s.count(s[i])
+ if count > 1:
+ s.remove(s[i])
+
+ for i in range(len(s)):
+ if i != len(s) - 1:
+ s[i] += " + "
+ string = "".join(s)
+
+ return string
+
+
+def same_var_and(string):
+
+ s = string.split(' + ')
+
+ for i in range(len(s)):
+ length = len(s[i])
+ sub_string = s[i]
+ count_same = 0
+ # check for same chars
+ for j in range(length):
+ for k in range(length):
+ if j == k:
+ continue
+ else:
+ if sub_string[k] is sub_string[j]:
+ count_same += 1
+
+ if count_same > 0:
+ hold = list(s[i])
+
+ for j in range(len(hold) - 1):
+ count = hold.count(hold[j])
+ if count > 1:
+ hold.remove(hold[j])
+
+ s[i] = "".join(hold)
+
+ for i in range(len(s)):
+ if i != len(s) - 1:
+ s[i] += " + "
+
+ string = "".join(s)
+
+ return string
+
+
+def simplify_complement_or(string):
+ string = replace_complement(string)
+
+ s = string.split(" + ")
+
+ for i in range(len(s)):
+ for j in range(len(s)):
+ if i == j:
+ continue
+ else:
+ if len(s[i]) > 1:
+ continue
+ else:
+ s[i] = s[i].upper()
+
+ if s[j] == s[i]:
+ s[j] = ""
+ s[i] = "1"
+ else:
+ s[i] = s[i].lower()
+
+ new_s = []
+
+ for i in range(len(s)):
+ if s[i] == "":
+ continue
+ else:
+ new_s.append(s[i])
+
+ for i in range(len(new_s)):
+ if i != len(new_s) - 1:
+ new_s[i] += " + "
+
+ string = "".join(new_s)
+
+ return string
+
+
+def simplify_complement_and(string):
+ string = replace_complement(string)
+
+ s = string.split(" + ")
+
+ for i in range(len(s)):
+
+ hold = list(s[i])
+
+ for j in range(len(hold)):
+ for k in range(len(hold)):
+ if j == k:
+ continue
+ else:
+ hold[j] = hold[j].upper()
+
+ if hold[k] == hold[j]:
+ hold[k] = ""
+ hold[j] = "0"
+ else:
+ hold[j] = hold[j].lower()
+ new_hold = []
+
+ for j in range(len(hold)):
+ if hold[j] == "":
+ continue
+ else:
+ new_hold.append(hold[j])
+
+ s[i] = "".join(new_hold)
+
+ for i in range(len(s) - 1):
+ if i != len(s) - 1:
+ s[i] += " + "
+
+ string = "".join(s)
+
+ return string
diff --git a/BDD pavlos/BDDs/test_simplify.py b/BDD pavlos/BDDs/test_simplify.py
new file mode 100644
index 0000000..9868769
--- /dev/null
+++ b/BDD pavlos/BDDs/test_simplify.py
@@ -0,0 +1,66 @@
+import simplify
+
+# contains functions for building each step of the BDD
+
+
+def simplify_all(string):
+
+ # 10 simplifications just in case
+ for i in range(10):
+ string = simplify.replace_complement(string)
+ string = simplify.same_var_and(string)
+ string = simplify.same_var_or(string)
+
+ string = simplify.simplify_complement_or(string)
+ string = simplify.same_var_and(string)
+ string = simplify.same_var_or(string)
+
+ string = simplify.simplify_complement_and(string)
+ string = simplify.same_var_and(string)
+ string = simplify.same_var_or(string)
+
+ string = simplify.simplify_0(string)
+ string = simplify.simplify_1(string)
+ string = simplify.same_var_and(string)
+ string = simplify.same_var_or(string)
+
+ return string
+
+
+def put_0(string, var):
+
+ variable = str(var)
+
+ string = string.replace(variable, "0")
+ string = string.replace(variable.upper(), "1")
+
+ return string
+
+
+def put_1(string, var):
+
+ variable = str(var)
+
+ string = string.replace(variable, "1")
+ string = string.replace(variable.upper(), "0")
+
+ return string
+
+
+# use these two for each loop in the sequence list
+def build_0(string, var):
+
+ string = put_0(string, var)
+
+ string = simplify_all(string)
+
+ return string
+
+
+def build_1(string, var):
+
+ string = put_1(string, var)
+
+ string = simplify_all(string)
+
+ return string