finitefield.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
class FINITE_FIELD < $STR,$HASH,$IS_LT{FINITE_FIELD}
class FINITE_FIELD < $STR,$HASH,$IS_LT{FINITE_FIELD} is
include COMPARABLE;
shared default_base:INT;
attr n, p:INT; -- n mod (p)
set_base(base:INT) is
if base.is_neg then base:=-base; end;
default_base:=#(base);
end;
create(i:INT, base:INT):SAME is
set_base(base); res:SAME:=new; res.p:=default_base;
m::=i%default_base; if m.is_non_neg then res.n:=m; else res.n:=m+default_base; end;
return res;
end;
create(i:INT):SAME is return #(i,default_base); end;
create(i:CARD):SAME is return #(i.int,default_base); end;
create(i:INTI):SAME is return #( (i%default_base.inti).int ,default_base); end;
copy:SAME is return #(n,p); end;
zero:SAME is return #(0); end;
one:SAME is return #(1); end;
is_eq(o:SAME):BOOL is return (n=o.n)and(p=o.p); end;
is_lt(o:SAME):BOOL pre p=o.p is return compare(o)=-1; end;
compare(o:SAME):INT is
if n<o.n then return -1; elsif n>o.n then return 1.int; else return 0.int; end;
end;
sgn:INT is return ((p/2.int)-n).sgn; end;
abs:SAME is return self; end;
is_zero:BOOL is return n.is_zero; end;
is_one:BOOL is return n.is_one; end;
hash:CARD is return n.card; end;
int:INT is return n; end;
inti:INTI is return n.inti; end;
card:CARD is return n.card; end;
str:STR is return n.str; end;
str(lib : LIBCHARS) : STR is return str; end;
inspect:STR is return "["+n.str+"%"+p.str+"]"; end;
negate:SAME is return #(-n,p); end;
inverse:SAME pre n.is_non_zero is return #(INT_EXT::inv(p,n), p); end;
plus(o:SAME):SAME pre p=o.p is return #(n+o.n, p); end;
plus(o:INT):SAME is return #(n+o, p); end;
plus(o:CARD):SAME is return #(n+o.int, p); end;
minus(o:SAME):SAME pre p=o.p is return #(n-o.n, p); end;
minus(o:INT):SAME is return #(n-o, p); end;
minus(o:CARD):SAME is return #(n-o.int, p); end;
times(o:SAME):SAME pre p=o.p is return #(n*o.n, p); end;
times(o:INT):SAME is return #(n*o,p); end;
times(o:CARD):SAME is return #(n*o.int,p); end;
pow(i:INT):SAME is
if i.is_neg then return inverse^(-i); else return #(INT_EXT::power_mod(n,i,p), p);end;
end;
pow(i:CARD):SAME is return pow(i.int); end;
div(o:SAME):SAME pre o.n.is_non_zero and (p=o.p) is return times(o.inverse); end;
div(i:INT):SAME is return #(n*INT_EXT::inv(p,i),p); end;
div(i:CARD):SAME is return div(i.int); end;
up!:SAME is
-- Yield successive from self to `p-1'.
p0::=p; loop r::=n.upto!(p0-1.int); yield #(r,p0); end;
end;
for_all!:SAME is
-- Yield successive from #(0) to #(p-1).
loop r::=0.int.upto!(default_base-1.int); yield #(r); end;
end;
for_all_pos!:SAME is
-- Yield successive from #(1) to #(p-1).
loop r::=1.int.upto!(default_base-1.int); yield #(r); end;
end;
end;
class TEST_FINITE_FIELD
class TEST_FINITE_FIELD is
include TEST;
test_f_field is
class_name("FINITE_FIELD");
p:INT:=11.int;
f,f1,f2,f3:FINITE_FIELD;
f:=#(17.int,p); test("generate", f.str, 6.str);
f1:=#(15); test("plus", (f+f1).str, 10.str);
f1:=#(-1); test("plus", (f+f1).str, 5.str);
test("plus", (f+3).str, 9.str);
--
f1:=#(3); test("minus", (f-f1).str, 3.str);
f1:=#(-3); test("minus", (f-f1).str, 9.str);
test("minus", (f-3).str, 3.str);
--
f1:=#(3); test("times", (f*f1).str, 7.str);
f1:=#(-3); test("times", (f*f1).str, 4.str);
test("times", (f*3).str, 7.str);
--
f1:=#(3); test("invese", (f1*f1.inverse).str,1.str);
--
f1:=#(3); test("div", (f/f1).str, 2.str);
f1:=#(-3); test("div", (f/f1).str, 9.str);
test("div", (f/3).str, 2.str);
finish;
end;
main is
test_f_field;
end;
end;