# -*- coding: utf-8 -*-
"""
Builds the classic 'Umbrella' decision net and uses it to find the utility of 
each decision choice and the optimal decision, given a certain weather condition.

For netica version 6.05 or later

@author: Sophie
"""
import sys, os
sys.path.append(os.path.abspath('..'))
import neticapy as netica

env = netica.Environ()

net = netica.Net("Umbrella")	

weather = net.new_node("Weather", 2)
forecast = net.new_node("Forecast", 3)
umbrella = net.new_node("Umbrella", 2)
umbrella.kind = "DECISION"
satisfaction = net.new_node("Satisfaction", 0)
satisfaction.kind = "UTILITY"

forecast.state_names = "sunny, cloudy, rainy"
weather.state_names = "sunshine, rain"
umbrella.state_names = "take_umbrealla, dont_take_umbrella"

forecast.add_link_from(weather)
umbrella.add_link_from(forecast)
satisfaction.add_link_from(weather)
satisfaction.add_link_from(umbrella)
	
weather.set_CPT([1, 1], [0.7, 0.3])

forecast.set_CPT([0], [0.7, 0.2, 0.1])
forecast.set_CPT([1], [0.15, 0.25, 0.6])

satisfaction.set_func_real([0, 0], 20)
satisfaction.set_func_real([0, 1], 100)
satisfaction.set_func_real([1, 0], 70)
satisfaction.set_func_real([1, 1], 0)

net.compile_net()

# 1st type of usage:  To get the expected utilities, given the current findings

forecast.enter_finding("sunny")	
utils = umbrella.get_expected_utils()

print("If the forecast is sunny, expected utility of", 
      umbrella.get_state_name(0), "is",
      utils[0], "and of", umbrella.get_state_name(1), "is", utils[1])

# 2nd type of usage:  To get the optimal decision table

net.retract_findings()
umbrella.get_expected_utils()            # causes Netica to recompute decision tables, given current findings
	                                      # (which in this case are no findings)

for fs in range(forecast.num_states):
    decision = umbrella.get_func_state([fs])
    print("If the forecast is", forecast.get_state_name(fs), 
          "the best decision is", umbrella.get_state_name(decision))   

res, mesg = env.close_netica()
print(mesg)
