[mercury-users] About unification and AI
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Apr 26 07:05:09 AEST 2004
On 23-Apr-2004, Maurizio Colucci <seguso.forever at tin.it> wrote:
> demon:-
Rather than using assertions that update a global database which is
implicitly visible everwhere, in Mercury you would explicitly pass the
database as an argument.
So in Mercury, this would be
demon(Database0, Database) :-
or
demon(!Database) :-
> % try all the matchings between events and rules...
> forall( (rule(Pre, Inf),
> member(P, Pre),
> eventDef(_, E),
> P = E), % this unification binds variables globally!
> % P, Pre, Inf are all changed!
> ( remove2(P, Pre, Pre2), % obvious
> ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences(
> Pre2,
> (Pre, Inf)))).
In Mercury, you would use aggregate or unsorted_aggregate
(from the std_util module) instead of forall/2.
demon(Database0, Database) :-
aggregate(
(pred((P,Pre,Inf,RuleVars)::out) is nondet :-
rule(Pre, Inf, RuleVars0, Database0),
member(P, Pre),
eventDef(_, E, Database0),
unify(P, E, RuleVars0, RuleVars)),
(pred((P_,Pre_,Inf_,RuleVars_)::in, Db0::in, Db::out) is det :-
remove2(P_, Pre_, Pre2),
ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences(
Pre2, (Pre_, Inf_), RuleVars_, Db0, Db)),
Database0,
Database).
Here "RuleVars" is a varset which holds the bindings of the variables in the
rule, and unify/4 is the one from samples/interpreter.m (which really ought
to go in the Mercury standard library).
> ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences([], Rule):-
> assertAllInferencesAndDerivations(Rule).
> ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences(
> Pre, Rule):-
> forall( ( member(P, Pre),
> eventDef(_, Ev),
> P=Ev), % Inference has been instantiated too.
> ( remove2(P, Pre, Pre2),
> ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences(Pre2, Rule))).
This would be handled similarly to the one above.
> ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences(_, _):-
> abort(ifThePreconditionsAreAllSatisfiedThenAssertTheConsequences-failed).
This would be unnecessary in Mercury -- just declare the procedure as
"det" (or "cc_multi" if you're using unsorted_aggregate), and then the
compiler will ensure that it can't fail.
> assertAllInferencesAndDerivations(Rule):-
> Rule = (Preconditions, Inferences),
> integrityCheck(ground(Preconditions)),
> ( thisStuffIsAlreadyAsserted(Rule)->true
> ;
> ( free_variables(Inferences, FreeVars), % The power of prolog :-)
In Mercury, you could use
assertAllInferencesAndDerivations(Rule, RuleVars, Db0, Db):-
integrityCheck(term.is_ground(Preconditions)),
( thisStuffIsAlreadyAsserted(Rule, Db0)->true
;
( free_variables(Inferences, RuleVars, FreeVars),
...
where
:- func free_variables(term, varset) = list(var).
free_variables(Term, VarSet) = FreeVars :-
BoundVars = map.keys(varset.get_bindings(VarSet)),
FreeVars = list.delete_all(term.vars(Term), BoundVars).
> bindEachFreeVarToANewConstant(FreeVars),
In Mercury, you could use
bindEachFreeVarToANewConstant(FreeVars, Db0, Db),
where the database type would have a field that records the next
available constant.
--
Fergus Henderson | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list