-module(surreal). -export([leq/2, eq/2, isnumber/1, add/2, leftset/1, rightset/1, test/0, allsubsets/1, gen/1, filternumbers/1, simplify/1, gt/2, lt/2, ne/2, geq/2, setmax/1, setmin/1]). % 0 = ({}, {}) % -1 = ({}, {0}) % 1 = ({0}, {}) %Nzero = { [], [] }. %Nmone = { [], [Nzero] }. %None = { [Nzero], [] }. % ({}, {-1}) < -1 < ({-1},{0}) < 0 < ({0}, {1}) < 1 < ({1},{}) % 0.5 = ({0}, {1}) % -0.5 = ({-1},{0}) %Nhalf= { [Nzero], [None] }. %Nmhalf= { [Nmone], [Nzero] }. % ({-1,0},{1}) == ({0},{1}) % ({},{-1,0}) == ({},{-1}) % note: { L,R } == { max(L) , min(R) } % todo: figure out if there is a simpler way of testing if a list is setempty setempty([]) -> true; setempty(_) -> false. % these 3 functions specify that a surreal number is represente by a tupple leftset({L,_}) -> L. rightset({_,R}) -> R. set2num(L,R) -> {L,R}. setunion(A,B) -> lists:umerge(A,B). % x <= y iff !(y<=x.left) && !(y.right<=x) leq(X,Y) -> % true=isnumber(X), true=isnumber(Y), setempty([ XL || XL <- leftset(X), leq(Y,XL) ]) and setempty([ YR || YR <- rightset(Y), leq(YR,X) ]). eq(X,Y) -> leq(X,Y) and leq(Y,X). ne(X,Y) -> not eq(X,Y). gt(X,Y) -> not leq(X,Y). lt(X,Y) -> leq(X,Y) and ne(X,Y). geq(X,Y) -> not lt(X,Y). setmax([]) -> []; setmax([H|T]) -> [setmima(T, H, fun gt/2)]. setmin([]) -> []; setmin([H|T]) -> [setmima(T, H, fun lt/2)]. setmima([H|T], Max, OP) -> case OP(H, Max) of true -> setmima(T, H, OP); false -> setmima(T, Max, OP) end; setmima([], Max, _) -> Max. % ∀ x∈L, ∀ y∈R : !(y<=x) isnumber(X) -> setempty([ 1 || L <- leftset(X), R <- rightset(X), leq(R,L) ]) . % addition % x+y = ( (Xl+y) v (Yl+x), (Xr+y) v (Yr+x) ) add(X,Y) -> % true=isnumber(X), true=isnumber(Y), set2num( setunion( [ add(XL,Y) || XL <- leftset(X) ], [ add(X,YL) || YL <- leftset(Y) ] ), setunion( [ add(XR,Y) || XR <- rightset(X) ], [ add(X,YR) || YR <- rightset(Y) ] ) ). simplify(A) -> set2num(setmax(leftset(A)), setmin(rightset(A))). gen(0) -> []; gen(N) ->G= gen(N-1), filternumbers([ set2num(L,R) || L <-allsubsets(G), R<-allsubsets(G) ] ). filternumbers([H|T]) -> case isnumber(H) of true -> [ H | filternumbers(T) ]; false -> filternumbers(T) end; filternumbers([]) -> []. allsubsets([]) -> [[]]; allsubsets([H]) -> [ [], [H] ]; allsubsets([H|T]) -> [ X || X<-allsubsets(T) ] ++ [ [H|X] || X<-allsubsets(T) ]. test() -> % generation 1 Nzero= set2num([],[]), true= isnumber(Nzero), % generation 2 Nmone = set2num( [], [Nzero] ), None = set2num( [Nzero], [] ), Nzz= set2num( [Nzero], [Nzero] ), true= isnumber(Nmone), true= isnumber(None), false=isnumber(Nzz), Nzero1= set2num([Nmone],[None]), Nhalf= set2num( [Nzero], [None] ), Nmhalf= set2num( [Nmone], [Nzero] ), N3half= set2num( [], [None] ), Ntwo= add(None,None), Nmtwo= add(Nmone,Nmone), Nthree= add(None,Ntwo), Nfour= add(None,Nthree), Nmthree= add(Nmone,Nmtwo), Nmfour= add(Nmone,Nmthree), false= isnumber(set2num([None], [Nmone])), true= isnumber(Nhalf), true= isnumber(N3half), true= isnumber(Nmhalf), true= isnumber(Ntwo), true= isnumber(Nthree), true= leq(Nmone, Nmhalf), true= leq(Nmhalf, Nzero), true= leq(Nzero, Nhalf), true= leq(Nhalf, None), false= leq(Nmhalf, Nmone), false= leq(Nzero, Nmhalf), false= leq(Nhalf, Nzero), false= leq(None, Nhalf), true= eq(add(Nhalf,Nhalf),None), true= eq(add(Nmhalf,Nhalf),Nzero), true= eq(add(None, Nmone), Nzero), true= eq(add(Ntwo, Ntwo), Nfour), true= eq(add(Ntwo, None), Nthree), false= eq(None, Nzero), false= eq(Nmone, Nzero), true= isnumber(None), NRLIST=[Nmone, Nzero, None], [ leq(A,B) || A<-NRLIST, B<-NRLIST ]. % [ % eq(add(add(N3half, N3half), add(N3half, N3half)), Nzero), % eq(add(add(N3half, N3half), add(N3half, N3half)), None), % eq(add(add(N3half, N3half), add(N3half, N3half)), Ntwo), % eq(add(add(N3half, N3half), add(N3half, N3half)), Nthree), % eq(add(add(N3half, N3half), add(N3half, N3half)), Nfour), % % eq(add(add(N3half, N3half), N3half), Nzero), % eq(add(add(N3half, N3half), N3half), None), % eq(add(add(N3half, N3half), N3half), Ntwo), % eq(add(add(N3half, N3half), N3half), Nthree), % eq(add(add(N3half, N3half), N3half), Nfour), % % eq(add(N3half, add(N3half, N3half)), Nzero), % eq(add(N3half, add(N3half, N3half)), None), % eq(add(N3half, add(N3half, N3half)), Ntwo), % eq(add(N3half, add(N3half, N3half)), Nthree), % eq(add(N3half, add(N3half, N3half)), Nfour), % % eq(add(N3half, N3half), Nzero), % eq(add(N3half, N3half), None), % eq(add(N3half, N3half), Ntwo), % eq(add(N3half, N3half), Nthree), % eq(add(N3half, N3half), Nfour) % ]