Advertisement
Cybernetic1

Untitled

Apr 16th, 2012
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. %% Backward chaining
  2.  
  3. -module(backward).
  4. -export([start/0,mainLoop/0,solveGoal/2,solveRule/2,collect/3]).
  5.  
  6. start() ->
  7.     %% Initialize KB
  8.     ets:new(rules, [bag, named_table]),
  9.     ets:insert(rules, {g,[d,e,f,h,i,j],1.0}),
  10.     ets:insert(rules, {g,[a,b,c],1.1}),
  11.     ets:insert(rules, {a,[],0.1}),
  12.     ets:insert(rules, {b,[],0.2}),
  13.     ets:insert(rules, {c,[],0.3}),
  14.     ets:insert(rules, {d,[],0.4}),
  15.     ets:insert(rules, {e,[],0.5}),
  16.     ets:insert(rules, {f,[],0.6}),
  17.     ets:insert(rules, {h,[],0.7}),
  18.     ets:insert(rules, {i,[],0.8}),
  19.     ets:insert(rules, {j,[],0.9}),
  20.     mainLoop().
  21.  
  22. mainLoop() ->
  23.     Query = io:read("Enter query: "),
  24.     if
  25.         Query == {ok, x} -> exit(normal);
  26.         true -> ok
  27.     end,
  28.     Daddy = spawn(backward, solveGoal, [element(2, Query), self()]),
  29.     receive
  30.         {_, Truth} -> io:format("Answer is: ~w~n", [Truth]),
  31.                       exit(Daddy, ok)
  32.     end,
  33.     mainLoop().
  34.  
  35. solveGoal(Goal, Caller) ->
  36.     %% Fetch rules...
  37.     ApplicableRules = ets:match(rules,{Goal, '$1', '$2'}),
  38.     lists:foreach(
  39.         fun([RuleBody,Truth]) ->
  40.         if
  41.             %% If RHS is null
  42.             RuleBody == [] -> Caller ! {Goal, Truth};
  43.             %% If RHS contains subgoals
  44.             true -> spawn_link(backward, solveRule, [RuleBody, self()])
  45.         end end,
  46.         ApplicableRules),
  47.     receive
  48.         %% Each message is of the form {goal,truth}
  49.         %% Just accept the 1st answer
  50.         {_, Truth} -> Caller ! {Goal, Truth}         
  51.     end.
  52.  
  53. solveRule(RuleTail, Caller) ->
  54.     N = length(RuleTail),
  55.     Collector = spawn_link(backward, collect, [[], N, Caller]),
  56.     %% For each subgoal in Rule
  57.     %% Spawn a process to solve each subgoal
  58.     lists:foreach(
  59.         fun(Subgoal) -> spawn_link(backward, solveGoal, [Subgoal, Collector]) end,
  60.         RuleTail).
  61.  
  62. %% Accumulate results
  63. collect(Truths, N, Caller) ->
  64.     %% If we have N messages send back the answer
  65.     %% Answer = min of truth values, equivalent to fuzzy-logic AND
  66.     if length(Truths) == N -> Caller ! {dont_care, lists:sum(Truths)};
  67.        true -> true
  68.     end,
  69.     receive
  70.         {_, Truth} -> collect([Truth | Truths], N, Caller)
  71.     end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement