Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %% Backward chaining
- -module(backward).
- -export([start/0,solveGoal/2,solveRule/2,collect/3,unify/2]).
- start() ->
- Query = io:read("Enter query: "),
- solveGoal(element(2, Query), self()),
- receive
- {_, Truth} -> io:format("Answer is: ~w~n", [Truth])
- end.
- solveGoal(Goal,Caller) ->
- %% Fetch rules...
- Rule = case Goal of
- g -> [g,a,b,c];
- a -> [a];
- b -> [b];
- c -> [c]
- end,
- Applicable = backward:unify(Goal,Rule),
- if Applicable == true ->
- if
- %% If RHS is null
- tl(Rule) == [] -> Caller ! {Goal,0.9};
- %% If RHS contains subgoals
- true -> spawn(backward, solveRule, [tl(Rule), self()])
- end
- %% If unify fails do nothing
- end,
- receive
- %% Each message is of the form {goal,truth}
- %% Just accept the 1st answer
- {_, Truth} -> Caller ! {Goal, Truth}
- end.
- solveRule(RuleTail, Caller) ->
- N = length(RuleTail),
- Collector = spawn(backward, collect, [[], N, Caller]),
- %% For each subgoal in Rule
- %% Spawn a process to solve each subgoal
- lists:map(fun(Subgoal) -> spawn(backward, solveGoal, [Subgoal, Collector]) end,
- RuleTail).
- %% Accumulate results
- collect(Truths, N, Caller) ->
- %% If we have N messages send back the answer
- %% Answer = min of list, equivalent to fuzzy-logic AND
- if length(Truths) == N -> Caller ! {dont_care, lists:min(Truths)};
- true -> true
- end,
- receive
- {_, Truth} -> collect([Truth | Truths], N, Caller)
- end.
- %% Unify: just a stub
- unify(Goal,Rule) -> Goal == hd(Rule).
Advertisement
Add Comment
Please, Sign In to add comment