Current section
Files
Jump to
Current section
Files
lib/nop/element/rule.ex
defmodule NOP.Element.Rule do
defmacro __using__([]) do
quote do
use GenServer
use NOP.Element.LogicElement
def start_link(rule_name, fbe_list) do
#create_element_list needs to be defined!
element_list = create_element_list(fbe_list)
# create_instigation_list needs to be defined
instigation_list = create_instigation_list(fbe_list)
state = init_state(rule_name, element_list, instigation_list)
state = init_condition_list(state)
state = reset_statistics_to_state(state)
#{:ok, pid} = GenServer.start_link(__MODULE__, state, name: String.to_atom(rule_name))
{:ok, pid} = GenServer.start_link(__MODULE__, state)
link_to_elements(element_list, pid, rule_name)
{:ok, pid}
end
def init(state) do
{:ok, state}
end
def handle_cast(:run_manual, state) do
Logger.debug("Rule #{get_name(state)} launching instigatins manualy")
run_instigations(state)
{:noreply, state}
end
defp init_state(rule_name, element_list, instigation_list) do
values = evaluate_elements(rule_name, element_list)
result = evaluate_rule(rule_name, values)
%{
:name => rule_name,
:element_list => element_list,
:values => values,
:result => result,
:instigation_list => instigation_list
}
end
defp get_instigation_list_from_state(state) do
Map.get(state, :instigation_list)
end
defp evaluate_rule(rule_name, premise_list) do
premise_aux = Map.to_list(premise_list)
result = evaluate_rule_int(premise_aux, true)
Logger.debug(
"Evaluating rule #{rule_name} with conditions #{inspect(premise_aux)} = #{result}"
)
result
end
defp evaluate_rule_int(_any, false) do
#Stop assert on first false
false
end
defp evaluate_rule_int([], result) do
result
end
defp evaluate_rule_int([{_name, assert} | element_list], result) do
evaluate_rule_int(element_list, result and assert)
end
defp run_instigations(state) do
# Run each instigation in a separated task
instigation_list = get_instigation_list_from_state(state)
run_instigations_int(instigation_list)
end
defp run_instigations_int([]) do
# Finished
end
defp run_instigations_int([{module, method, args} | instigation_list]) do
Task.start(module, method, args)
run_instigations_int(instigation_list)
end
defp run_instigations_int([method | instigation_list]) do
Task.start(method)
run_instigations_int(instigation_list)
end
defp update_my_state(state, name, _element_name, element_values, old_result) do
result = evaluate_rule(name, element_values)
if result != old_result and result do
Logger.debug("Rule #{name} launching instigations after assert true")
run_instigations(state)
end
result
end
end
end
end