Dear Twan,

Here are a few answers and comments to your message.

On Sat, Jan 17, 2009 at 1:07 PM, Nanitous <[email protected]> wrote:

> Hi,
>
> I accidentally stumbled over a neat programming trick which I want to share
> with other Oz users.
>
> I'm not sure whether my explaination of /why/ the trick works is correct,
> if its not, I surely would
> like to hear what's wrong with it.
>
> Inspired by the CTM Wiki page "99 problems in other languages:Oz"
> (
> http://codepoetics.com/wiki/index.php?title=Topics:99_Problems_in_other_languages:Oz
> )
> I've been converting a number of prolog sample programs (originating
> from 
> http://kti.mff.cuni.cz/~bartak/prolog/combinatorics.html<http://kti.mff.cuni.cz/%7Ebartak/prolog/combinatorics.html>)
> into Oz as an
> exercise using the guidelines described in CTM section 9.7.3 "Translating
> Prolog into a relational program".
>
> Because these sample programs are written in pure prolog, the guidelines
> make that
> conversion effortless, but the resulting translation less elegantly
> expresses the
> program than the original prolog clauses.
>
> Let me illustrate it by means of a contrived example, using relational
> style:
>
> (* In prolog: *)
> fact(0,1).
> fact(1,1).
> fact(N,F) :- N>1, N1 is N-1, fact(N1, FN), F is N*FN.
>
> Using the CTM guidelines, these clauses translate into Oz:
> (note the use of the deterministic choice by the if-statement)
> proc {Fact N F}
>        if N==0 then F=1
>        elseif N==1 then F=1
>        elseif N>1 then
>                FN in
>                {Fact N-1 FN}
>                F = N*FN
>        else
>                fail
>        end
> end
> % The next line just demonstrates the computation of 6! :
> {ExploreOne proc{$ F} {Fact 6 F} end}


Well, the 'if' statements make the code a bit cluttered.  You can also use
pattern matching with the 'case' statement.  I personally find it much more
readable:

proc {Fact N F}
   case N
   of 0 then F=1
   [] 1 then F=1
   [] N andthen N>1 then FN in {Fact N-1 FN} F=N*FN
   end
end

It is obvious that the lay-out and relatively large amount of text
> of the Oz translation leaves something to be desired. It would have
> been nice to be able to write:
>
> proc {Fact N F}
>        choice
>                N==0 F=1
>        []  N==1 then F=1
>        [] FN in
>                N > 1
>                {Fact N-1 FN}
>                F = N*FN
>        end
> end
>
> The textual structure of this procedure is less cluttered and follows
> the structure or the original prolog clauses closely. Moreover the use of
> the choice-statement keeps its semantics close the prolog-semantics of
> its original.
>
> But 'N==0', 'N==1' and 'N>1' are expressions and the Oz compiler will
> complain and tell you it doesn't accept expression where it expects
> statements.


Why don't you simply write N=0 to constrain N to be equal to 0?  You can
force more general boolean expressions to be true by... unifying them with
true.  See:

proc {Fact N F}
   choice
      N=0 F=1
   [] N=1 F=1
   [] FN in (N>1)=true {Fact N-1 FN} F=N*FN
   end
end

Don't ask me why I tried it, but I did.  I used the FD constraint
> propagators instead
> of the expressions; that is,  "N>:1" instead of "N>1" and so on:
>
> proc {Fact N F}
>        choice
>                N=:0 F=1
>        []  N=:1 F=1
>        [] FN in
>                N >: 1
>                {Fact N-1 FN}
>                F = N*FN
>        end
> end
>
> % And find the answer by using, e.g.
> {Browse {Seach.base.one proc{$ F} {Fact 6 F} end}.1 }
>
> At first I was suprised that this even would work, it seemed something like
> magic.
> One would expect constraint propagators to need a constraint store and
> all other required CSP trappings.


There is no magic.  The memory store of Oz *is* a constraint store by
definition.  In the core language, it only supports equality constraints.

Moreover, the constraint N>:1 expects N to be either a FD variable *or* an
integer.  An integer is seen as a determined FD variable.  That is why you
don't need to declare N as a constraint variable if it is determined
already.  If N is determined, N>:1 simply checks the constraint, and
succeeds or fail.


> But if you think a little bit further, I think, it is an obvious (side)
> effect.
> All constraint propagators must either return 'entailed', 'sleep', or
> 'failed'
> (See the "constraint extension tutorial" ) to the current computation
> space.
> In case of a fail, the computation space failes and the search engine
> explores the next choice points (See also Christian Schulte's excellent
> "Programming
> Constraint Services").  Since we use the same search engine for CSP as well
> as well to explore the choice points in {Fact}, the comparison
> constraint propagators, we can expect the same behaviour.


What you expect is what actually happens.  In your particular case, the
constraint propagator simply never sleeps.

Cheers,
raph
_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to