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) state = set_name(state, rule_name) #{: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