#! /usr/bin/env python

#
# STEP 1: IMPORT LIBs
#
# This part should be the same for every complexity evaluation script
# except "../../src" should point to directory of decisiondiagram.py 
#
import sys
sys.path.append("../../src")
import decisiondiagram
import functools

#
# STEP 2 (OPTIONAL): SOME SHORTCUTS
#
ite = decisiondiagram.ite
evaluate = decisiondiagram.evaluate
combine = decisiondiagram.combine
reorder = decisiondiagram.reorder
merge = decisiondiagram.merge
produceDD = decisiondiagram.produceDD

#
# STEP 3: IMPORT THE TARGET MODEl
#
model_name = "models/power_control"
model = __import__( model_name )

#
# STEP 4: PRODUCE THE DECISION DIAGRAM OF FUNCTIONS BY BRUTE-FORCE SEARCH
#
# decision diagrams of functions for power source allocations
left = produceDD({0:2, 1:2, 2:2, 3:2, 4:2, 5:2, 6:2, 7:2, 8:2}, [0, 1, 2, 3, 4, 5, 6, 7, 8], model.left_trsfun)
right = produceDD({0:2, 1:2, 2:2, 3:2, 4:2, 5:2, 6:2, 7:2, 8:2}, [0, 1, 2, 3, 4, 5, 6, 7, 8], model.right_trsfun)

# decision diagrams of FSM functions producing the intermediate states for power control
left_fsm = produceDD({9:4, 10:4}, [9, 10], model.left_fsm)
right_fsm = produceDD({11:4, 12:4}, [11, 12], model.right_fsm)

left = ite(left, [evaluate(left_fsm, {10:0}), evaluate(left_fsm, {10:1}), evaluate(left_fsm, {10:2}), evaluate(left_fsm, {10:3})])
right = ite(right, [evaluate(right_fsm, {12:0}), evaluate(right_fsm, {12:1}), evaluate(right_fsm, {12:2}), evaluate(right_fsm, {12:3})])

# decision diagrams of functions producing the control signals for engines, APU, and switches 1-6
control_functions = []
for i in range(9):
	fun = functools.partial(model.control_trsfun, output_bit=i)
	control = produceDD({13:4, 14:4}, [13, 14], fun)
#
# STEP 6: COMPOSE DECISION DIAGRAMS
#
	tmpdd = (ite(left, [evaluate(control, {13:0}), evaluate(control, {13:1}), evaluate(control, {13:2}), evaluate(control, {13:3})]))
	control_functions.append(ite(right, [evaluate(tmpdd, {14:0}), evaluate(tmpdd, {14:1}), evaluate(tmpdd, {14:2}), evaluate(tmpdd, {14:3})]))


complexity = merge(control_functions)

function034 = merge([control_functions[i] for i in [0, 3, 4]])

function03 = merge([control_functions[i] for i in [0, 3]])

function178 = merge([control_functions[i] for i in [1, 7, 8]])

function17 = merge([control_functions[i] for i in [1, 7]])

function25 = merge([control_functions[i] for i in [2, 5]])

function6 = merge([control_functions[i] for i in [6]])

function68 = merge([control_functions[i] for i in [6, 8]])

function468 = merge([control_functions[i] for i in [4, 6, 8]])

#
# STEP 7: OUTPUT COMPLEXITY
#
print "Complexity of the functional models: "
print "Complexity of the system:                          ", complexity.countPath()

print "Complexity of logic cone partition 1: "
print "Complexity of function of control signals 0, 3:    ", function03.countPath()
print "Complexity of function of control signals 1, 7:    ", function17.countPath()
print "Complexity of function of control signals 2, 5:    " , function25.countPath()
print "Complexity of function of control signals 4, 6, 8: ", function468.countPath()

print "Complexity of logic cone partition 2: "
print "Complexity of function of control signals 0, 3, 4: ", function034.countPath()
print "Complexity of function of control signals 2, 5:    " , function25.countPath()
print "Complexity of function of control signals 1, 7, 8: ", function178.countPath()
print "Complexity of function of control signal  6:       ", function6.countPath()

print "Complexity of logic cone partition 3: "
print "Complexity of function of control signals 0, 3, 4: ", function034.countPath()
print "Complexity of function of control signals 1, 7:    ", function17.countPath()
print "Complexity of function of control signals 2, 5:    " , function25.countPath()
print "Complexity of function of control signals 6, 8:    ", function68.countPath()

print "Conclusions: "
print "a. Partition 1 and 3 are better than partition 2 in terms of the sum of complexities."
print "b. Partition 3 is more balanced than partition 1."

#
# STEP 8 (OPTIONAL): VISUALIZE THE RESULTING DECISION DIAGRAMS
#

print "Done."


