ALS
Inscrit le: 11 Sep 2006 Messages: 647
|
Posté le: 23 Jan 2017 11:37 Sujet du message: Module orienté objet |
|
|
Bonjour à tous,
Nouveauté dans MAPLE 2016 : on connaissait déjà la structure de module dans les versions antérieures, mais cette nouvelle version permet d'effectuer de la programmation orientée objet, avec le module muni de la nouvelle option object et la fonction Object permettant de construire un objet.
Un exemple de module orienté objet sur l'arithmétique modulaire, tiré d'une page d'aide du logiciel.
a mod b signifie a modulo b, reste de la division euclidienne de a par b.
Exemple: 13 mod 5 = 3, car 13= 5*2 + 3.
Code: |
> restart:
> module IntMod()
option object;
local base := 1;
local value := 0;
# implement a ModuleApply and ModuleCopy routine
# to use IntMod() as a object constructor
export ModuleApply::static := proc()
Object( IntMod, _passed );
end;
export ModuleCopy::Static := proc( self::IntMod, proto::IntMod,
v::integer, b::integer, $ )
if ( _npassed < 3 ) then
# if a value was not given, copy the prototype
self:-value := proto:-value;
else
# use the given value
self:-value := v;
end;
if ( _npassed < 4 ) then
# if a base was not given, opy the prototype
self:-base := proto:-base;
else
# use the given base
self:-base := b;
end;
# apply the mod
self:-value := self:-value mod self:-base;
end;
# implement ModulePrint to make the display nice
export ModulePrint::static := proc( self::IntMod )
nprintf( "%d mod %d", self:-value, self:-base );
end;
# Implement Module type to enable type checking with
# with a specified base
export ModuleType::static := proc( self, type, b, $ )
if ( _npassed = 2 ) then
true;
else
evalb( self:-base = b );
end;
end;
# accessor to get the stored value
export getValue::static := proc( self::IntMod )
self:-value;
end;
# implement the + operator to allow IntMods to work properly
# in sum statements. We assume that the modular arthemetic is
# contagious and the entire addition become modular
export `+`::static := proc( )
local ints, imods, total, base, other;
# remove the stuff we aren't going to manipulate
( ints, other ) := selectremove( type, [_passed],
{ 'IntMod', 'integer' } );
( imods, ints ) := selectremove( type, ints, 'IntMod' );
base := imods[1]:-base;
if ( not andmap( type, imods, 'IntMod'( base ) ) ) then
error "all IntMods must be of the same base"
end;
#Add the IntMods and the integer constant, if one exists
total := ( `if`( numelems(ints) > 0, ints[1], 0 ) +
add( getValue(i), i in imods ) ) mod base;
# return a sequence
IntMod( total, base ), op( other );
end;
# implement the * operator
export `*`::static := proc( )
local ints, imods, total, base, other;
# remove the stuff we aren't going to manipulate
( ints, other ) := selectremove( type, [_passed],
{ 'IntMod', 'integer' } );
( imods, ints ) := selectremove( type, ints, 'IntMod' );
base := imods[1]:-base;
if ( not andmap( type, imods, 'IntMod'( base ) ) ) then
error "all IntMods must be of the same base"
end;
# remove the stuff we aren't going to manipulate
total := ( `if`( numelems(ints) > 0, ints[1], 1 ) *
add( getValue(i), i in imods ) ) mod base;
# return a sequence
IntMod( total, base ), op( other );
end;
# implement the ^ operator
export `^`::static := proc( self::IntMod, exponent::integer, $ )
IntMod( self:-value^exponent, self:-base );
end;
# implement the basic comparison operators
export `=`::static := proc( self::IntMod, other::IntMod, $ )
evalb( self:-base = other:-base and
self:-value = other:-value )
end;
export `<`::static := proc( self::IntMod, other::IntMod, $ )
evalb( self:-base = other:-base and
self:-value < other:-value )
end;
export `<=`::static := proc( self::IntMod, other::IntMod, $ )
evalb( self:-base = other:-base and
self:-value <= other:-value )
end;
export `>`::static := proc( self::IntMod, other::IntMod, $ )
evalb( self:-base = other:-base and
self:-value > other:-value )
end;
export `>=`::static := proc( self::IntMod, other::IntMod, $ )
evalb( self:-base = other:-base and
self:-value >= other:-value )
end;
# override the convert routine to allow IntMods to be converted
# to integers. The inverse does not work because we con't know
# which base to use
export convert::static := proc( v, toType, $ )
if ( v::IntMod ) then
if ( toType = ':-integer' ) then
v:-value;
else
error "cannot convert from IntMod to %1", toType;
end;
else
error "cannot convert into IntMod from %1", v
end;
end;
end:
|
A bientôt. |
|