 |
My Project
debian-1:4.1.1-p2+ds-4build3
|
Go to the source code of this file.
|
BOOLEAN | nrnDBTest (number a, const char *f, const int l, const coeffs r) |
|
static void | nrnCoeffWrite (const coeffs r, BOOLEAN) |
|
static char * | nrnCoeffName (const coeffs r) |
|
static BOOLEAN | nrnCoeffsEqual (const coeffs r, n_coeffType n, void *parameter) |
|
static char * | nrnCoeffString (const coeffs r) |
|
static void | nrnKillChar (coeffs r) |
|
static coeffs | nrnQuot1 (number c, const coeffs r) |
|
static number | nrnCopy (number a, const coeffs) |
|
static number | nrnInit (long i, const coeffs r) |
|
static void | nrnDelete (number *a, const coeffs) |
|
static int | nrnSize (number a, const coeffs) |
|
static long | nrnInt (number &n, const coeffs) |
|
static number | nrnMult (number a, number b, const coeffs r) |
|
static void | nrnPower (number a, int i, number *result, const coeffs r) |
|
static number | nrnAdd (number a, number b, const coeffs r) |
|
static number | nrnSub (number a, number b, const coeffs r) |
|
static BOOLEAN | nrnIsZero (number a, const coeffs) |
|
static number | nrnNeg (number c, const coeffs r) |
|
static number | nrnInvers (number c, const coeffs r) |
|
static number | nrnGcd (number a, number b, const coeffs r) |
|
static number | nrnLcm (number a, number b, const coeffs r) |
|
static number | nrnExtGcd (number a, number b, number *s, number *t, const coeffs r) |
|
static BOOLEAN | nrnIsOne (number a, const coeffs) |
|
static BOOLEAN | nrnEqual (number a, number b, const coeffs) |
|
static number | nrnGetUnit (number k, const coeffs r) |
|
static number | nrnXExtGcd (number a, number b, number *s, number *t, number *u, number *v, const coeffs r) |
|
static BOOLEAN | nrnIsMOne (number a, const coeffs r) |
|
static BOOLEAN | nrnGreater (number a, number b, const coeffs) |
|
static BOOLEAN | nrnGreaterZero (number k, const coeffs) |
|
static BOOLEAN | nrnIsUnit (number a, const coeffs r) |
|
static number | nrnAnn (number k, const coeffs r) |
|
static BOOLEAN | nrnDivBy (number a, number b, const coeffs r) |
|
static int | nrnDivComp (number a, number b, const coeffs r) |
|
static number | nrnDiv (number a, number b, const coeffs r) |
|
static number | nrnMod (number a, number b, const coeffs r) |
|
static number | nrnIntDiv (number a, number b, const coeffs r) |
|
static number | nrnQuotRem (number a, number b, number *rem, const coeffs r) |
|
static number | nrnMapModN (number from, const coeffs, const coeffs dst) |
|
static number | nrnMap2toM (number from, const coeffs, const coeffs dst) |
|
static number | nrnMapZp (number from, const coeffs, const coeffs dst) |
|
number | nrnMapGMP (number from, const coeffs, const coeffs dst) |
|
static number | nrnMapQ (number from, const coeffs src, const coeffs dst) |
|
static number | nrnMapZ (number from, const coeffs src, const coeffs dst) |
|
nMapFunc | nrnSetMap (const coeffs src, const coeffs dst) |
|
static void | nrnSetExp (unsigned long m, coeffs r) |
|
static void | nrnInitExp (unsigned long m, coeffs r) |
|
static const char * | nlCPEatLongC (char *s, mpz_ptr i) |
|
static const char * | nrnRead (const char *s, number *a, const coeffs r) |
|
BOOLEAN | nrnInitChar (coeffs r, void *p) |
|
◆ nrnWrite
◆ nlCPEatLongC()
static const char* nlCPEatLongC |
( |
char * |
s, |
|
|
mpz_ptr |
i |
|
) |
| |
|
static |
Definition at line 867 of file rmodulon.cc.
869 const char * start=
s;
870 if (!(*
s >=
'0' && *
s <=
'9'))
872 mpz_init_set_ui(
i, 1);
876 while (*
s >=
'0' && *
s <=
'9')
s++;
879 mpz_set_str(
i,start,10);
885 mpz_set_str(
i,start,10);
◆ nrnAdd()
static number nrnAdd |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 198 of file rmodulon.cc.
202 mpz_add(erg, (mpz_ptr)a, (mpz_ptr)
b);
203 mpz_mod(erg, erg, r->modNumber);
◆ nrnAnn()
Definition at line 494 of file rmodulon.cc.
498 mpz_gcd(tmp, (mpz_ptr)
k, r->modNumber);
499 if (mpz_cmp_si(tmp, 1)==0) {
503 mpz_divexact(tmp, r->modNumber, tmp);
◆ nrnCoeffName()
Definition at line 51 of file rmodulon.cc.
54 size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) + 2;
57 s= mpz_get_str (
s, 10, r->modBase);
◆ nrnCoeffsEqual()
Definition at line 67 of file rmodulon.cc.
70 return (n==
n_Zn) && (mpz_cmp_ui(r->modNumber,(
long)parameter)==0);
◆ nrnCoeffString()
Definition at line 73 of file rmodulon.cc.
75 size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) +2;
77 b= mpz_get_str (
b, 10, r->modBase);
80 else sprintf(
s,
"ZZ/(bigint(%s)^%lu)",
b,r->modExponent);
◆ nrnCoeffWrite()
Definition at line 38 of file rmodulon.cc.
40 size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) + 2;
42 s= mpz_get_str (
s, 10, r->modBase);
◆ nrnCopy()
static number nrnCopy |
( |
number |
a, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 138 of file rmodulon.cc.
141 mpz_init_set(erg, (mpz_ptr) a);
◆ nrnDBTest()
Definition at line 852 of file rmodulon.cc.
855 if ( (
mpz_sgn1((mpz_ptr) a) < 0) || (mpz_cmp((mpz_ptr) a, r->modNumber) > 0) )
857 Warn(
"mod-n: out of range at %s:%d\n",
f,
l);
◆ nrnDelete()
static void nrnDelete |
( |
number * |
a, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 156 of file rmodulon.cc.
158 if (*a ==
NULL)
return;
159 mpz_clear((mpz_ptr) *a);
◆ nrnDiv()
static number nrnDiv |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 529 of file rmodulon.cc.
531 if (a ==
NULL) a = (number)r->modNumber;
534 if (mpz_divisible_p((mpz_ptr)a, (mpz_ptr)
b))
536 mpz_divexact(erg, (mpz_ptr)a, (mpz_ptr)
b);
542 mpz_divexact(erg, (mpz_ptr)
b,
gcd);
545 WerrorS(
"Division not possible, even by cancelling zero divisors.");
546 WerrorS(
"Result is integer division without remainder.");
547 mpz_tdiv_q(erg, (mpz_ptr) a, (mpz_ptr)
b);
552 mpz_ptr tmp = (mpz_ptr)
nrnInvers((number) erg,r);
553 mpz_divexact(erg, (mpz_ptr)a,
gcd);
554 mpz_mul(erg, erg, tmp);
557 mpz_mod(erg, erg, r->modNumber);
◆ nrnDivBy()
Definition at line 507 of file rmodulon.cc.
510 return mpz_divisible_p(r->modNumber, (mpz_ptr)
b);
514 mpz_tdiv_q((mpz_ptr)n, (mpz_ptr)
b, (mpz_ptr)n);
◆ nrnDivComp()
static int nrnDivComp |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 521 of file rmodulon.cc.
524 if (mpz_divisible_p((mpz_ptr) a, (mpz_ptr)
b))
return -1;
525 if (mpz_divisible_p((mpz_ptr)
b, (mpz_ptr) a))
return 1;
◆ nrnEqual()
static BOOLEAN nrnEqual |
( |
number |
a, |
|
|
number |
b, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 321 of file rmodulon.cc.
323 return 0 == mpz_cmp((mpz_ptr)a, (mpz_ptr)
b);
◆ nrnExtGcd()
static number nrnExtGcd |
( |
number |
a, |
|
|
number |
b, |
|
|
number * |
s, |
|
|
number * |
t, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 297 of file rmodulon.cc.
305 mpz_gcdext(erg, bs, bt, (mpz_ptr)a, (mpz_ptr)
b);
306 mpz_mod(bs, bs, r->modNumber);
307 mpz_mod(bt, bt, r->modNumber);
◆ nrnGcd()
static number nrnGcd |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 244 of file rmodulon.cc.
248 mpz_init_set(erg, r->modNumber);
249 if (a !=
NULL) mpz_gcd(erg, erg, (mpz_ptr)a);
250 if (
b !=
NULL) mpz_gcd(erg, erg, (mpz_ptr)
b);
251 if(mpz_cmp(erg,r->modNumber)==0)
◆ nrnGetUnit()
Definition at line 326 of file rmodulon.cc.
328 if (mpz_divisible_p(r->modNumber, (mpz_ptr)
k))
return nrnInit(1,r);
330 mpz_ptr unit = (mpz_ptr)
nrnGcd(
k, 0, r);
331 mpz_tdiv_q(unit, (mpz_ptr)
k, unit);
332 mpz_ptr
gcd = (mpz_ptr)
nrnGcd((number)unit, 0, r);
337 mpz_ptr tmp = (mpz_ptr)
nrnMult((number) unit,(number) unit,r);
339 mpz_ptr gcd_new = (mpz_ptr)
nrnGcd((number) tmp, 0, r);
347 mpz_mul(tmp, tmp, unit);
348 mpz_mod(tmp, tmp, r->modNumber);
350 mpz_gcd(gcd_new, tmp, r->modNumber);
353 mpz_tdiv_q(tmp, r->modNumber, gcd_new);
354 mpz_add(unit, unit, tmp);
355 mpz_mod(unit, unit, r->modNumber);
◆ nrnGreater()
static BOOLEAN nrnGreater |
( |
number |
a, |
|
|
number |
b, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 476 of file rmodulon.cc.
478 return 0 < mpz_cmp((mpz_ptr)a, (mpz_ptr)
b);
◆ nrnGreaterZero()
◆ nrnInit()
Definition at line 148 of file rmodulon.cc.
151 mpz_init_set_si(erg,
i);
152 mpz_mod(erg, erg, r->modNumber);
◆ nrnInitChar()
Definition at line 903 of file rmodulon.cc.
907 r->modBase= (mpz_ptr)
nrnCopy((number)
info->base, r);
915 r->ch = mpz_get_ui(r->modNumber);
◆ nrnInitExp()
static void nrnInitExp |
( |
unsigned long |
m, |
|
|
coeffs |
r |
|
) |
| |
|
static |
◆ nrnInt()
static long nrnInt |
( |
number & |
n, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 173 of file rmodulon.cc.
175 return mpz_get_si((mpz_ptr) n);
◆ nrnIntDiv()
static number nrnIntDiv |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 594 of file rmodulon.cc.
598 if (a ==
NULL) a = (number)r->modNumber;
599 mpz_tdiv_q(erg, (mpz_ptr)a, (mpz_ptr)
b);
◆ nrnInvers()
Definition at line 232 of file rmodulon.cc.
236 mpz_invert(erg, (mpz_ptr)c, r->modNumber);
◆ nrnIsMOne()
Definition at line 463 of file rmodulon.cc.
469 mpz_t t; mpz_init_set(t, (mpz_ptr)a);
471 bool erg = (0 == mpz_cmp(t, r->modNumber));
◆ nrnIsOne()
Definition at line 313 of file rmodulon.cc.
318 return 0 == mpz_cmp_si((mpz_ptr)a, 1);
◆ nrnIsUnit()
◆ nrnIsZero()
Definition at line 216 of file rmodulon.cc.
221 return 0 == mpz_cmpabs_ui((mpz_ptr)a, 0);
◆ nrnKillChar()
static void nrnKillChar |
( |
coeffs |
r | ) |
|
|
static |
Definition at line 85 of file rmodulon.cc.
87 mpz_clear(r->modNumber);
88 mpz_clear(r->modBase);
◆ nrnLcm()
static number nrnLcm |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 264 of file rmodulon.cc.
268 mpz_lcm((mpz_ptr)erg, (mpz_ptr)erg, (mpz_ptr)tmp);
◆ nrnMap2toM()
Definition at line 661 of file rmodulon.cc.
665 mpz_mul_ui(erg,
nrnMapCoef, (
unsigned long)from);
666 mpz_mod(erg, erg, dst->modNumber);
◆ nrnMapGMP()
Definition at line 680 of file rmodulon.cc.
684 mpz_mod(erg, (mpz_ptr)from, dst->modNumber);
◆ nrnMapModN()
◆ nrnMapQ()
Definition at line 688 of file rmodulon.cc.
692 nlGMP(from, erg, src);
693 mpz_mod(erg, erg, dst->modNumber);
◆ nrnMapZ()
◆ nrnMapZp()
Definition at line 670 of file rmodulon.cc.
676 mpz_mod(erg, erg, dst->modNumber);
◆ nrnMod()
static number nrnMod |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 562 of file rmodulon.cc.
586 mpz_init_set_ui(rr, 0);
587 mpz_gcd(
g, (mpz_ptr)r->modNumber, (mpz_ptr)
b);
588 if (mpz_cmp_si(
g, 1L) != 0) mpz_mod(rr, (mpz_ptr)a,
g);
◆ nrnMult()
static number nrnMult |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 181 of file rmodulon.cc.
185 mpz_mul(erg, (mpz_ptr)a, (mpz_ptr)
b);
186 mpz_mod(erg, erg, r->modNumber);
◆ nrnNeg()
Definition at line 224 of file rmodulon.cc.
228 mpz_sub((mpz_ptr)c, r->modNumber, (mpz_ptr)c);
◆ nrnPower()
static void nrnPower |
( |
number |
a, |
|
|
int |
i, |
|
|
number * |
result, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 190 of file rmodulon.cc.
194 mpz_powm_ui(erg, (mpz_ptr)a,
i, r->modNumber);
◆ nrnQuot1()
Definition at line 93 of file rmodulon.cc.
96 long ch = r->cfInt(c, r);
98 mpz_init_set(a, r->modNumber);
99 mpz_init_set_ui(
b, ch);
103 if(mpz_cmp_ui(
gcd, 1) == 0)
105 WerrorS(
"constant in q-ideal is coprime to modulus in ground ring");
106 WerrorS(
"Unable to create qring!");
109 if(r->modExponent == 1)
113 info.exp = (
unsigned long) 1;
119 info.base = r->modBase;
122 mpz_init(baseTokNew);
123 mpz_set(baseTokNew, r->modBase);
124 while(mpz_cmp(
gcd, baseTokNew) > 0)
127 mpz_mul(baseTokNew, baseTokNew, r->modBase);
131 mpz_clear(baseTokNew);
◆ nrnQuotRem()
static number nrnQuotRem |
( |
number |
a, |
|
|
number |
b, |
|
|
number * |
rem, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 618 of file rmodulon.cc.
626 mpz_init_set(aa, (mpz_ptr)a);
627 mpz_init_set(bb, (mpz_ptr)
b);
629 mpz_gcd(
g, bb, r->modNumber);
635 mpz_div(
g, r->modNumber,
g);
636 mpz_invert(
g, bb,
g);
◆ nrnRead()
Definition at line 891 of file rmodulon.cc.
897 mpz_mod(z, z, r->modNumber);
◆ nrnSetExp()
static void nrnSetExp |
( |
unsigned long |
m, |
|
|
coeffs |
r |
|
) |
| |
|
static |
Definition at line 829 of file rmodulon.cc.
832 if (r->modNumber !=
NULL) mpz_clear(r->modNumber);
836 mpz_init_set (r->modNumber, r->modBase);
837 mpz_pow_ui (r->modNumber, r->modNumber,
m);
◆ nrnSetMap()
Definition at line 744 of file rmodulon.cc.
764 && (mpz_cmp(src->modBase, dst->modBase) == 0)
765 && (src->modExponent == dst->modExponent))
return nrnMapGMP;
772 mpz_init_set_si(nrnMapModul, src->ch);
776 mpz_init(nrnMapModul);
777 mpz_set(nrnMapModul, src->modNumber);
786 if (mpz_divisible_p(nrnMapModul, dst->modNumber))
793 mpz_divexact(
nrnMapCoef, dst->modNumber, nrnMapModul);
794 mpz_ptr tmp = dst->modNumber;
795 dst->modNumber = nrnMapModul;
798 dst->modNumber = tmp;
803 dst->modNumber = tmp;
◆ nrnSize()
static int nrnSize |
( |
number |
a, |
|
|
const |
coeffs |
|
) |
| |
|
static |
Definition at line 164 of file rmodulon.cc.
166 if (a ==
NULL)
return 0;
167 return sizeof(mpz_t);
◆ nrnSub()
static number nrnSub |
( |
number |
a, |
|
|
number |
b, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 207 of file rmodulon.cc.
211 mpz_sub(erg, (mpz_ptr)a, (mpz_ptr)
b);
212 mpz_mod(erg, erg, r->modNumber);
◆ nrnXExtGcd()
static number nrnXExtGcd |
( |
number |
a, |
|
|
number |
b, |
|
|
number * |
s, |
|
|
number * |
t, |
|
|
number * |
u, |
|
|
number * |
v, |
|
|
const coeffs |
r |
|
) |
| |
|
static |
Definition at line 372 of file rmodulon.cc.
381 nrnWrite(xx = (number)r->modNumber, r);
393 mpz_init_set(bs, (mpz_ptr) a);
394 mpz_init_set(bt, (mpz_ptr)
b);
397 mpz_gcd(erg, bs, bt);
404 mpz_gcd(erg, erg, r->modNumber);
406 mpz_div(bs, bs, erg);
407 mpz_div(bt, bt, erg);
414 mpz_gcdext(one, bu, bv, bs, bt);
432 mpz_init_set(uu, (mpz_ptr)ui);
451 mpz_mod(bs, bs, r->modNumber);
452 mpz_mod(bt, bt, r->modNumber);
453 mpz_mod(bu, bu, r->modNumber);
454 mpz_mod(bv, bv, r->modNumber);
◆ gmp_nrz_bin
◆ nrnCoeffName_buff
char* nrnCoeffName_buff =NULL |
|
static |
◆ nrnMapCoef
mpz_ptr nrnMapCoef = NULL |
|
static |
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
@ n_rep_gap_rat
(number), see longrat.h
static number nrnMult(number a, number b, const coeffs r)
@ n_rep_gmp
(mpz_ptr), see rmodulon,h
@ n_Zn
only used if HAVE_RINGS is defined
static BOOLEAN nrnGreaterZero(number k, const coeffs)
static char * nrnCoeffName_buff
static mpz_ptr nrnMapCoef
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
void StringAppendS(const char *st)
static char * nrnCoeffName(const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
static number nrnMapZp(number from, const coeffs, const coeffs dst)
static BOOLEAN nrnIsMOne(number a, const coeffs r)
static BOOLEAN nrnDivBy(number a, number b, const coeffs r)
static int nrnSize(number a, const coeffs)
static number nrnGetUnit(number k, const coeffs r)
static number nrnInvers(number c, const coeffs r)
static long nrnInt(number &n, const coeffs)
static BOOLEAN nrnIsZero(number a, const coeffs)
static number nrnMod(number a, number b, const coeffs r)
static BOOLEAN nrnGreater(number a, number b, const coeffs)
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
@ n_Znm
only used if HAVE_RINGS is defined
static void nrnInitExp(unsigned long m, coeffs r)
nMapFunc nrnSetMap(const coeffs src, const coeffs dst)
static number nrnQuotRem(number a, number b, number *rem, const coeffs r)
static number nrnMap2toM(number from, const coeffs, const coeffs dst)
static number nrnDiv(number a, number b, const coeffs r)
static BOOLEAN nrnIsOne(number a, const coeffs)
static number nrnSub(number a, number b, const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
static FORCE_INLINE void n_Write(number n, const coeffs r, const BOOLEAN bShortOut=TRUE)
void PrintS(const char *s)
static coeffs nrnQuot1(number c, const coeffs r)
static number nrnGcd(number a, number b, const coeffs r)
#define omFreeSize(addr, size)
static const char * nrnRead(const char *s, number *a, const coeffs r)
static void nrnKillChar(coeffs r)
static BOOLEAN nrnIsUnit(number a, const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
static void nrnSetExp(unsigned long m, coeffs r)
static number nrnMapModN(number from, const coeffs, const coeffs dst)
static number nrnLcm(number a, number b, const coeffs r)
static int nrnDivComp(number a, number b, const coeffs r)
static number nrnAnn(number k, const coeffs r)
static number nrnCopy(number a, const coeffs)
static number nrnMapZ(number from, const coeffs src, const coeffs dst)
static number nrnMapQ(number from, const coeffs src, const coeffs dst)
static char * nrnCoeffString(const coeffs r)
void mpz_mul_si(mpz_ptr r, mpz_srcptr s, long int si)
void StringSetS(const char *st)
number nrnMapGMP(number from, const coeffs, const coeffs dst)
static const char * nlCPEatLongC(char *s, mpz_ptr i)
void WerrorS(const char *s)
static number nrnXExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
static number nrnInit(long i, const coeffs r)
const Variable & v
< [in] a sqrfree bivariate poly
const CanonicalForm int s
static number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r)
static void nrnCoeffWrite(const coeffs r, BOOLEAN)
static number nrnNeg(number c, const coeffs r)
static BOOLEAN nrnCoeffsEqual(const coeffs r, n_coeffType n, void *parameter)
#define omFreeBin(addr, bin)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
const ExtensionInfo & info
< [in] sqrfree poly
static number nrnAdd(number a, number b, const coeffs r)
static void nrnPower(number a, int i, number *result, const coeffs r)
BOOLEAN nrnDBTest(number a, const char *f, const int l, const coeffs r)
void rem(unsigned long *a, unsigned long *q, unsigned long p, int °a, int degq)
static BOOLEAN nrnEqual(number a, number b, const coeffs)
static void nrnDelete(number *a, const coeffs)
void nlGMP(number &i, mpz_t n, const coeffs r)
@ n_rep_gap_gmp
(), see rinteger.h, new impl.