View difference between Paste ID: br5bj8iV and r1tmLdir
SHOW: | | - or go back to the newest paste.
1
%% Backward chaining
2
3
-module(backward).
4
-export([start/0,solveGoal/2,solveRule/2,collect/3,unify/2]).
5
6
start() ->
7
	Query = io:read("Enter query: "),
8
	solveGoal(element(2, Query), self()),
9
	receive
10
		{_, Truth} -> io:format("Answer is: ~w~n", [Truth])
11
	end.
12
13-
solveGoal(Goal,Caller) ->
13+
solveGoal(Goal, Caller) ->
14
    %% Fetch rules...
15
	Rule = case Goal of
16
		g -> [g,a,b,c];
17
		a -> [a];
18
		b -> [b];
19
		c -> [c]
20
	end,
21-
	Applicable = backward:unify(Goal,Rule),
21+
	Applicable = backward:unify(Goal, Rule),
22
	if Applicable == true ->
23
		if 
24
			%% If RHS is null
25-
			tl(Rule) == [] -> Caller ! {Goal,0.9};
25+
			tl(Rule) == [] -> Caller ! {Goal, 0.9};
26
			%% If RHS contains subgoals
27
			true -> spawn(backward, solveRule, [tl(Rule), self()])
28
		end
29
	%% If unify fails do nothing
30
	end,
31
	receive
32
		%% Each message is of the form {goal,truth}
33
		%% Just accept the 1st answer
34
		{_, Truth} -> Caller ! {Goal, Truth}
35
	end.
36
37
solveRule(RuleTail, Caller) ->
38
	N = length(RuleTail),
39
	Collector = spawn(backward, collect, [[], N, Caller]),
40
	%% For each subgoal in Rule
41
	%% Spawn a process to solve each subgoal
42
	lists:map(fun(Subgoal) -> spawn(backward, solveGoal, [Subgoal, Collector]) end,
43
		RuleTail).
44
45
%% Accumulate results
46
collect(Truths, N, Caller) ->
47
	%% If we have N messages send back the answer
48-
	%% Answer = min of list, equivalent to fuzzy-logic AND
48+
	%% Answer = min of truth values, equivalent to fuzzy-logic AND
49
	if length(Truths) == N -> Caller ! {dont_care, lists:min(Truths)};
50
	   true -> true
51
	end,
52
	receive
53
		{_, Truth} -> collect([Truth | Truths], N, Caller)
54
	end.
55
56
%% Unify: just a stub
57
unify(Goal,Rule) -> Goal == hd(Rule).