How to fight semideterminism in Mercury?
From: Dmitri Soshnikov (dsoshnikov_at_gmail.com)
Date: 10/17/04
- Previous message: Remko Troncon: "comp.lang.prolog Frequently Asked Questions"
- Next in thread: Bart Demoen: "Re: How to fight semideterminism in Mercury?"
- Reply: Bart Demoen: "Re: How to fight semideterminism in Mercury?"
- Reply: Ralph Becket: "Re: How to fight semideterminism in Mercury?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 16 Oct 2004 16:28:18 -0700
Hello,
Please excuse my rather newbie question. I am in the process of
getting acquainted with Mercury, and I have encountered one problem
with determinism inference that I am not sure how to tackle best. I am
writing a small logic programming textbook for students, and want to
switch half of the examples to Mercury, so I decided to implement AVL
search tree along the guidelines described in the Bratko's
"Programming in Prolog for Artificial Intelligence".
We need to keep the height of the tree at each point, so the type
definition looks like:
:- type tree(T) ---> nil; tree(T,avltree(T),avltree(T)).
:- type avltree(T) ---> tree(T)/int.
When we come to element addition predicate, it is defined as follows:
:- func add(int,avltree(int)) = avltree(int).
:- mode add(in,in) = out is semidet.
add(X,nil/_) = tree(X,nil/0,nil/0)/1.
add(X,tree(Y,L,R)/H) = Res :-
X<Y ->
tree(Z,L1,R1)/_ = add(X,L),
Res = combine(L1,Z,R1,Y,R);
X>Y ->
tree(Z,L1,R1)/_ = add(X,R),
Res = combine(L,Y,L1,Z,R1);
Res = tree(X,L,R)/H.
The problem is that the predicate should be deterministic, because
there is always one way to add an element to the tree (unlike the
Mercury library, I assume that if the element already exists, we just
keep the tree unchanged). However, Mercury mode inference does not
allow it to be deterministic, because at the point where we unify
"tree(Z,L1,R1)/_ = add(X,L)" there could be other solution, "nil/0",
returned by add, and this case is not considered in our definition.
However, WE KNOW that add always returns non-empty tree, but the
Mercury compiler naturally does not.
My question is: how to avoid this problem and define the predicate to
be deterministic? I see two possible directions:
1. Consider the case when add returns empty subtree. This would allow
for deterministic definition, but would be somewhat artificial - I
would be writing a code that would never execute! I think this is not
the right way to go for the modern programming language -- I believe
the language should let me know when the dead code exists, and not the
vice versa.
2. Define some other type for non-empty AVL tree, and declare that add
returns non-empty tree. However, at present I am not very sure how to
define this in Mercury.
I would be grateful for any possible help with solution of this
problem.
Thanks,
Dmitri.
- Previous message: Remko Troncon: "comp.lang.prolog Frequently Asked Questions"
- Next in thread: Bart Demoen: "Re: How to fight semideterminism in Mercury?"
- Reply: Bart Demoen: "Re: How to fight semideterminism in Mercury?"
- Reply: Ralph Becket: "Re: How to fight semideterminism in Mercury?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|
|