Re: Avoiding to repeat code ? (B-Prolog)



On Nov 3, 2:16 pm, Chip Eastham <hardm...@xxxxxxxxx> wrote:
On Nov 3, 8:37 am, Chip Eastham <hardm...@xxxxxxxxx> wrote:



On Nov 3, 7:13 am, Ecirbaf <fabrice.march...@xxxxxxxxx> wrote:

Hi,

I've just discovered B-Prolog here on the group.
It's quite amazing how it can easily solve problems.

Hacking an example Neng-Fa Zhou provided, here is below a program
that solves a 'still life problem' ( Conway game of life ) in a 3x3
square.

However I'm aware my coding is obviously bad.
Some code is duplicated several time, for example, each sum ( like Pm
+Zm+Zz+Zp+Pp ) is repeated 4 times.
Worse, the code that assert a cell is stable is repeated 9 times !

Please, how to avoid this code muliplication ?
Would it be possible to define some kind of "function" like in a
procedural language ?

Apologize for this very newbie stupid question.

Thanks for any advice.

Fabrice

solve(Vars):-
Vars=[Mp, Zp, Pp,
Mz, Zz, Pz,
Mm, Zm, Pm],
Vars :: 0..1,

% Stable corners
((#\Mm) #/\ ( ((Zm+Zz+Mz) #=< 2)
#\/((Zm+Zz+Mz) #>= 4) ))
#\/( Mm #/\ ( ((Zm+Zz+Mz) #= 2)
#\/((Zm+Zz+Mz) #= 3) )),

((#\Pm) #/\ ( ((Zm+Zz+Pz) #=< 2)
#\/((Zm+Zz+Pz) #>= 4) ))
#\/( Pm #/\ ( ((Zm+Zz+Pz) #= 2)
#\/((Zm+Zz+Pz) #= 3) )),

((#\Pp) #/\ ( ((Zp+Zz+Pz) #=< 2)
#\/((Zp+Zz+Pz) #>= 4) ))
#\/( Pp #/\ ( ((Zp+Zz+Pz) #= 2)
#\/((Zp+Zz+Pz) #= 3) )),

((#\Mp) #/\ ( ((Zp+Zz+Mz) #=< 2)
#\/((Zp+Zz+Mz) #>= 4) ))
#\/( Mp #/\ ( ((Zp+Zz+Mz) #= 2)
#\/((Zp+Zz+Mz) #= 3) )),

% Stable middle sides
((#\Zm) #/\ ( ((Pm+Pz+Zz+Mz+Mm) #=< 2)
#\/((Pm+Pz+Zz+Mz+Mm) #>= 4) ))
#\/( Zm #/\ ( ((Pm+Pz+Zz+Mz+Mm) #= 2)
#\/((Pm+Pz+Zz+Mz+Mm) #= 3) )),

((#\Pz) #/\ ( ((Pm+Zm+Zz+Zp+Pp) #=< 2)
#\/((Pm+Zm+Zz+Zp+Pp) #>= 4) ))
#\/( Pz #/\ ( ((Pm+Zm+Zz+Zp+Pp) #= 2)
#\/((Pm+Zm+Zz+Zp+Pp) #= 3) )),

((#\Zp) #/\ ( ((Mp+Mz+Zz+Pz+Pp) #=< 2)
#\/((Mp+Mz+Zz+Pz+Pp) #>= 4) ))
#\/( Zp #/\ ( ((Mp+Mz+Zz+Pz+Pp) #= 2)
#\/((Mp+Mz+Zz+Pz+Pp) #= 3) )),

((#\Mz) #/\ ( ((Mp+Zp+Zz+Zm+Mm) #=< 2)
#\/((Mp+Zp+Zz+Zm+Mm) #>= 4) ))
#\/( Mz #/\ ( ((Mp+Zp+Zz+Zm+Mm) #= 2)
#\/((Mp+Zp+Zz+Zm+Mm) #= 3) )),

% Stable center
((#\Zz) #/\ ( ((Mm+Zm+Pm+Pz+Pp+Zp+Mp+Mz) #=< 2)
#\/((Mm+Zm+Pm+Pz+Pp+Zp+Mp+Mz) #>= 4) ))
#\/( Zz #/\ ( ((Mm+Zm+Pm+Pz+Pp+Zp+Mp+Mz) #= 2)
#\/((Mm+Zm+Pm+Pz+Pp+Zp+Mp+Mz) #= 3) )),

% Really in 3 x 3
Mm #\/ Zm #\/ Pm,
Pm #\/ Pz #\/ Pp,
Pp #\/ Zp #\/ Mp,
Mp #\/ Mz #\/ Mm,

labeling(Vars).

I think what you want is to introduce some predicates
of your own and rules that define them.

For example, the code for "stable corners":

((#\Mm) #/\ ( ((Zm+Zz+Mz) #=< 2)
#\/((Zm+Zz+Mz) #>= 4) ))
#\/( Mm #/\ ( ((Zm+Zz+Mz) #= 2)
#\/((Zm+Zz+Mz) #= 3) ))

can be encapsulated in a clause for certain values:

stable_corner(Mm,Zm,Zz,Mz) :-
((#\Mm) #/\ ( ((Zm+Zz+Mz) #=< 2)
#\/((Zm+Zz+Mz) #>= 4) ))
#\/( Mm #/\ ( ((Zm+Zz+Mz) #= 2)
#\/((Zm+Zz+Mz) #= 3) )).

Then you can use the appropriate calls to this
predicates as goals, rather than repeating the
formula itself:

stable_corner(Mm,Zm,Zz,Mz),
stable_corner(Pm,Zm,Zz,Pz),
stable_corner(Pp,Zp,Zz,Pz),
stable_corner(Mp,Zp,Zz,Mz),...

followed by similar "abstractions" of the logic
for stable middle sides and stable center. In
fact you'll probably want to abstract the entire
rule for "still life", e.g.

still_life(Vars):-
Vars =[Mp, Zp, Pp,
Mz, Zz, Pz,
Mm, Zm, Pm],
Vars :: 0..1,
stable_corner(Mm,Zm,Zz,Mz),
stable_corner(Pm,Zm,Zz,Pz),
stable_corner(Pp,Zp,Zz,Pz),
stable_corner(Mp,Zp,Zz,Mz),
stable_mdside(Zm,Pm,Pz,Zz,Mz,Mm),
stable_mdside(Pz,Pm,Zm,Zz,Zp,Pp),
stable_mdside(Zp,Mp,Mz,Zz,Pz,Pp),
stable_mdside(Mz,Mp,Zp,Zz,Zm,Mm),
stable_center(Zz,Mm,Zm,Pm,Pz,Pp,Zp,Mp,Mz).

In fact using predicates/rules/clauses will
probably allow you to express the underlying
Game of Life in a more natural fashion.

See section 1.5 of the the B-Prolog User's
Manual for how to compile and load a file of
predicate definitions before interactively
querying against them:

[B-Prolog User's Manual by Neng-Fa Zhou]http://www.probp.com/download/manual.pdf

regards, chip

I got a write permission error when trying to compile
and load my file under B-Prolog (Windows version), but
I was able to consult the file (applies the rules
interactively rather than in compiled form). I got
these solutions:

| ?- solve(Vars).
Vars = [0,1,0,1,0,1,0,1,0] ?;
Vars = [0,1,0,1,0,1,0,1,1] ?;
Vars = [0,1,0,1,0,1,1,1,0] ?;
Vars = [0,1,1,1,0,1,0,1,0] ?;
Vars = [0,1,1,1,0,1,1,1,0] ?;
Vars = [1,1,0,1,0,1,0,1,0] ?;
Vars = [1,1,0,1,0,1,0,1,1] ?;
no

I'll follow up with Neng-fa Zhou to see what settings
are needed to fix the write permission error.

regards, chip


.



Relevant Pages

  • Re: Project proposal -- Forth project organiser
    ... they compile a call to an error routine instead. ... You load the file and each new defined word gets ... lot easier if people who write libraries do it your way. ... input buffer and check that it isn't a keeper word that hasn't been ...
    (comp.lang.forth)
  • Re: How to load and clear files?
    ... You can just load new definitions to replace the old ones. ... by the old name in the lisp image, ... CLISP is written in portable C code: you can compile it on almost any ... or:EXECUTE to precise your idea. ...
    (comp.lang.lisp)
  • Re: VB application crashes
    ... When I load the form in Private Sub Form_ActivateI have the ... These are functions that load data into Listviews, ... In VB6, in the project's properties, go to the Compile tab and select ... Run the EXE from Windows Explorer. ...
    (microsoft.public.vb.general.discussion)
  • Re: Problem with VB crashing
    ... updates. ... I shutdown VB, VB crashes (and displays the pop-up that says, "VB has ... They compile without any problem - and ... all I need to do is load the program (either ...
    (microsoft.public.vb.general.discussion)
  • Re: Problem with VB crashing
    ... I shutdown VB, VB crashes (and displays the pop-up that says, "VB has ... They compile without any problem - and ... all I need to do is load the program (either ...
    (microsoft.public.vb.general.discussion)