##################################################################### ##GeometryMiracles: Save this file as GeometryMiracles # ## To use it, stay in the # ##same directory, get into Maple (by typing: maple ) # ##and then type: read GeometryMiracles # ##Then follow the instructions given there # ## # ##Written by Doron Zeilberger, Rutgers University , # #zeilberg at math dot rutgers dot edu # ###################################################################### #Created: May-June, 2014 print(`Created: May-June 2014`): print(` This is GeometryMiracles `): print(`It is one of the packages that accompany the article `): print(` Enumerative Geometrical Genealogy (Or: The Sex Life of Points and Lines)`): print(`by Shalosh B. Ekhad and Doron Zeilberger`): print(`and also available from Zeilberger's website`): print(``): print(`Please report bugs to zeilberg at math dot rutgers dot edu`): print(``): print(`The most current version of this package and paper`): print(` are available from`): print(`http://www.math.rutgers.edu/~zeilberg/ .`): print(`--------------------------------------------------------------------------`): print(`For a list of the PLOTTING procedures type ezraP();, for help with`): print(`a specific procedure, type ezra(procedure_name); .`): print(``): print(`--------------------------------------------------------------------------`): print(`--------------------------------------------------------------------------`): print(`For a list of the SUPPORTING procedures type ezra1();, for help with`): print(`a specific procedure, type ezra(procedure_name); .`): print(``): print(`--------------------------------------------------------------------------`): print(`--------------------------------------------------------------------------`): print(`For a list of the MAIN procedures type ezra();, for help with`): print(`a specific procedure, type ezra(procedure_name); .`): print(``): print(`--------------------------------------------------------------------------`): with(combinat): with(linalg): with(plots): #ez:=proc(): print(`DrawPt(A,NA), DrawLeSegment(A,B,NA,NB), DrawLe(Li,K), DrawObj([[1,2],[4,5]],{1,2},P); `):end: ezraP:=proc() if args=NULL then print(` The plotting procedures are: DrawObj `): print(` `): else ezra(args): fi: end: ezra1:=proc() if args=NULL then print(` The supporting procedures are: `): print(` ApplyPer, AreCollinear, CS, EnumSeqR1, EnumSeqR1pure ,Esof, IsPt, IsPtCu, Le, Nodes1, Pt, Omek, `): print(` RanObjF1, RanObjF4a, Reps, Targem `): else ezra(args): fi: end: ezra:=proc(): if nargs=0 then print(`Contains procedures:`): print(` EnumSeq,EnumSeqPure, EnumSeqR, EnumSeqRpure, EvalCr, EvalCu, FindLines, Ge, GenLiP, GenLiPf, Nekudot, NekudotN, NekudotPure, NekudotNpure, PascalM, `): print(` PascalMr, PascalMrV, PascalMv, PascalMvWE, PentMr, PentMrPure, PentMrV, PopExp `): print(`QuadM, QuadMr, QuadMrV, QuadMv, QuadMvWE, RanLiP, RanLiPrat, RanLiPf, RanObjF, `): print(` RanObjF4, RanObjsF4, TtoC, Yesharim, YesharimN, YesharimPure, YesharimNpure `): elif nargs=1 and args[1]=ApplyPer then print(`ApplyPer(G,pi): applies the permutation pi to the object G, try`): print(`ApplyPer({{1,2},{3,4}},[2,1,4,3]);`): elif nargs=1 and args[1]=AreCollinear then print(`AreCollinear(L): if the three points in the list L collinear?, then it returns the equation of the line`): print(`else it returns FAIL`): print(`Try: `): print(` AreCollinear([[1,2],[2,4],[3,6]]); `): elif nargs=1 and args[1]=CS then print(`CS(Li): Given a list of five points, finds the unique conic section passing through them`): print(`Try: `): print(` CS([[1,3],[6,4],[16,41],[11,13],[5,2]]); `): elif nargs=1 and args[1]=DrawObj then print(`DrawObj(LiP,C,P,k): given a list of points LiP, and a creature C draws it without labels`): print(`Try:`): print(`DrawObj([[1,2],[4,5]],{1,2},P,3);`): elif nargs=1 and args[1]=EnumSeq then print(`EnumSeq(k,N): the first N terms of the enumeration sequence number of points (lines) in i-th generation`): print(`starting with k distinct, general points, at generation 0 `): print(`and then iterating taking all possible lines joining any two points when i is even, and `): print(`and all possible points of intersection of the previous generation if i is odd `): print(`Using generic symbolic points.(Warning: very slow) `): print(`Try:`): print(`EnumSeq(4,2);`): elif nargs=1 and args[1]=EnumSeqPure then print(`EnumSeq(k,N): the first N terms of the enumeration sequence number of points (lines) in i-th PURE generation`): print(`starting with k distinct, general points, at generation 0 `): print(`and then iterating taking all possible lines joining any two points when i is even, and `): print(`and all possible points of intersection of the previous generation if i is odd `): print(`Using generic symbolic points.(Warning: very slow) `): print(`Try:`): print(`EnumSeqPure(4,2);`): elif nargs=1 and args[1]=EnumSeqR then print(`EnumSeqR(k,N,K,r): the first N terms of the enumeration sequence number of points (lines) in i-th generation`): print(`starting with k distinct, general points, at generation 0 `): print(`and then iterating taking all possible lines joining any two points when i is even, and `): print(`and all possible points of intersection of the previous generation if i is odd `): print(`Using generic random points with complex parameters taken from 1 to K `): print(`It only uses r random choices. If they don't all agree that it returns FAIL `): print(`Warning: this is only semi-rigorous, but the higher the r, the surer it is.`): print(`Try:`): print(`EnumSeqR(4,2,100,4);`): elif nargs=1 and args[1]=EnumSeqR1 then print(`EnumSeqR1(k,N,K): the first N terms of the enumeration sequence number of points (lines) in i-th generation`): print(`starting with k distinct, general points, at generation 0 `): print(`and then iterating taking all possible lines joining any two points when i is even, and `): print(`and all possible points of intersection of the previous generation if i is odd `): print(`Using generic random points with complex parameters taken from 1 to K `): print(`It only uses ONE random choice `): print(`Try:`): print(`EnumSeqR1(4,2,100);`): elif nargs=1 and args[1]=EnumSeqRpure then print(`EnumSeqRpure(k,N,K,r): the first N terms of the enumeration sequence number of points (lines) in i-th PURE generation`): print(`starting with k distinct, general points, at generation 0 `): print(`and then iterating taking all possible lines joining any two points when i is even, and `): print(`and all possible points of intersection of the previous generation if i is odd `): print(`Using generic random points with complex parameters taken from 1 to K `): print(`It only uses r random choices. If they don't all agree that it returns FAIL `): print(`Warning: this is only semi-rigorous, but the higher the r, the surer it is.`): print(`Try:`): print(`EnumSeqRpure(4,2,100,4);`): elif nargs=1 and args[1]=Esof then print(`Esof(Li): given a set of pairs [Name,Objects], finds the set of distinct Objects,`): print(`and returns the list [Object,SetOfNamesWithThatObject]. For example, try:`): print(`Esof({[a,1],[b,1],[c,2],[d,3],[e,3]});`): elif nargs=1 and args[1]=EvalCr then print(`EvalCr(C,LiP): evaluates the creature C consisisting of the set of points LiP`): print(`Try:`): print(`EvalCr({1,2},[[2,3],[6,11]]);`): elif nargs=1 and args[1]=EvalCu then print(`EvalCu(LiP,C,v): given a list of points and a circuit C, and vertex i, evalutes it`): print(`Try: `): print(` EvalCu([[1,2],[4,5]],[[1],[2],{1,2}],3); `): elif nargs=1 and args[1]=FindLines then print(`FindLines(L): given a list of points L, [Name, pt], finds all triples [Ni,Nj,Nk] such that`): print(`L[i],L[j],L[k] are collinear. Try:`): print(`FindLines([[1,[1,1]],[2,[2,2]],[3,[3,3]],[4,[1,2]],[5,[1,3]]]);`): elif nargs=1 and args[1]=Ge then print(`Ge(LiP,C): the full story of the Genealogy of the last memeber of the circuit C`): print(`starting with the list of points LiP, try:`): print(`Ge([[a,b],[c,d]],[[1],[2],{1,2}]);`): elif nargs=1 and args[1]=GenLiP then print(`GenLiP(k,t,s): a generic list of k points phrased in terms of the indexed variables, t[1], ..., t[k], s[1], ..., s[k]`): print(`Try:`): print(`GenLiP(3,t,s);`): elif nargs=1 and args[1]=GenLiPf then print(`GenLiPf(k,t,f1,f2): a generic list of k points phrased in terms of the indexed variables, t[1],...,t[k]`): print(`lying on the parametric curve x=f1(t), y=f2(t), where f1 and f2 are expressions in t, try:`): print(`GenLiPf(3,t,t,t^2);`): print(`GenLiPf(3,t,(t+1/t)/2,(t-1/t)/2/I);`): elif nargs=1 and args[1]=IsPt then print(`IsPt(A): given a geometrical object decides wether it is`): print(`a point or not (or neither, then it returns FAIL)`): print(`Try: `): print(`IsPt({1,2}); `); elif nargs=1 and args[1]=IsPtCu then print(`IsPtCu(C,v): Given a circuit C, and a vertex v, decides whether it is a point`): print(`Try: `): print(` IsPtCu([[1],[2],{1,2}],3); `): elif nargs=1 and args[1]=Le then print(`Le(P1,P2), the line joining P1 and P2, where P1 and P2 are given a pair of numbers (or expressions) `): elif nargs=1 and args[1]=Nekudot then print(`Nekudot(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the points, with NAMES, in the k-th generation obtained by intersecting lines`): print(`in earlier generations, that are not already in an earlier generation.`): print(`Try:`): print(`Nekudot([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=NekudotPure then print(`NekudotPure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the points, with NAMES, in the k-th generation obtained by intersecting lines`): print(`in the previous generation of lines (called genartion k-1 of lines), that are not already in an earlier generations of points.`): print(`Try:`): print(`NekudotPure([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=NekudotN then print(`NekudotN(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the points in the k-th generation obtained by intersecting lines`): print(`in earlier generations, that are not already in an earlier generations.`): print(`Without Names. For a version with Names do Nekudot(P,k)`): print(`Try:`): print(`NekudotN([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=NekudotNpure then print(`NekudotNpure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the points in the k-th generation obtained by intersecting lines`): print(`in generation k of lines, that are not already in an earlier generations of points.`): print(`Without Names. For a version with Names do NekudotPure(P,k)`): print(`Try:`): print(`NekudotNpure([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=Nodes1 then print(`Nodes1(Cr): Inputs a creature, Cr (i.e. a tree) outputs all its leaves, followed by its interior vertices,`): print(`Try:`): print(`Nodes1({{1,2},{3,4}});`): elif nargs=1 and args[1]=Omek then print(`Omek(A): given a geometrical object finds its depth`): print(` Try: `): print(` Omek({1,2}); `): elif nargs=1 and args[1]=PascalM then print(`PascalM(t), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio.`): pritn(`It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2`): print(`where a parametric point is [t[i],t[i]^2]`): print(`Try: `): print(`PascalM(t); `): elif nargs=1 and args[1]=PascalMr then print(`PascalMr(K), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio.`): print(`where the points are drawn randomly with complex parameters with integers from 1 to K `): print(`Try: `): print(`PascalMr(40); `): elif nargs=1 and args[1]=PascalMrV then print(`PascalMrV(P,K), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio.`): print(`where the points are drawn randomly with complex parameters with integers from 1 to K `): print(`Verbose version. `): print(`Try: `): print(`PascalMrV(P,40); `): elif nargs=1 and args[1]=PascalMv then print(`PascalMv(P): vebose vesrion of PascalM(t), WITHOUT EQUATIONS`): print(` all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio.`): print(`Try: `): print(`PascalMv(P); `): elif nargs=1 and args[1]=PascalMvWE then print(`PascalMvWE(P,t): vebose vesrion of PascalM(t), WITHOUT EQUATIONS`): print(` all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio.`): pritn(`It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2`): print(`where a parametric point is [t[i],t[i]^2]`): print(`Try: `): print(`PascalMvWE(P,t); `): elif nargs=1 and args[1]=PentMr then print(`PentMr(K), all the miracles for a quadrilateral from second-generation lines.`): print(`using random points with complex parameters drawn from 1 to K `): print(`Try: `): print(`PentMr(100);`): elif nargs=1 and args[1]=PentMrPure then print(`PentMrPure(K), all the miracles for a quadrilateral from second-generation PURE lines.`): print(`using random points with complex parameters drawn from 1 to K `): print(`Try: `): print(`PentMrPure(100);`): elif nargs=1 and args[1]=PentMrV then print(`PentMrV(P,K), all the miracles for a quadrilateral from second-generation lines.`): print(`using random points with complex parameters drawn from 1 to K `): print(`VERBOSE version, using P to denote points.`): print(`Try: `): print(`PentMrV(P,40);`): elif nargs=1 and args[1]=Pt then print(`Pt(Le1,Le2), the point of intersection of Le1 and Le2`): print(`where Le1 and Le2 are given as a pair of numbers (or expressions) and [A,B] means the line A*x+B*y+1=0`): elif nargs=1 and args[1]=PopExp then print(`PopExp(n,K,R): starting with n points (taken randomly with complex coordinates with parameters from 1 to K`): print(`finds the cardinalities of successive generations, up to NekudotN(P,R)`): print(`Try:`): print(`PopExp(4,100,2);`): elif nargs=1 and args[1]=QuadM then print(`QuadM(s,t), all the miracles for a quadrilateral from second-generation points.`): print(`Try: `): print(`QuadM(s,t);`): elif nargs=1 and args[1]=QuadMr then print(`QuadMr(K), all the miracles for a quadrilateral from second-generation points.`): print(`using random points with complex parameters drawn from 1 to K `): print(`Try: `): print(`QuadMr(40);`): elif nargs=1 and args[1]=QuadMrV then print(`QuadMrV(P,K), all the miracles for a quadrilateral from second-generation points. Verbose version`): print(`It uses randomly-selected points with parameters with complex integer coordinates from 1 to K`): print(`P is a letter designating indexed points.`): print(`Try`): print(`QuadMrV(P,40);`): elif nargs=1 and args[1]=QuadMv then print(`QuadMv(P), all the miracles for a quadrilateral from second-generation points. Verbose version`): print(`Try`): print(`QuadMv(P);`): elif nargs=1 and args[1]=QuadMvWE then print(`QuadMvWE(s,t,P), all the miracles for a quadrilateral from second-generation points. Verbose version`): print(`With Equations!`): print(`Try`): print(`QuadMvWE(s,t,P);`): elif nargs=1 and args[1]=RanLiP then print(`RanLiP(k,K): a list of k random points with complex, integer, coordinates, drawn from 1 to K`): print(`Try:`): print(`RanLiP(5,100);`): elif nargs=1 and args[1]=RanLiPf then print(`RanLiPf(k,K,t,f1,f2): a random list of k points `): print(`lying on the parametric curve x=f1(t), y=f2(t), where f1 and f2 are expressions in t.`): print(`where the parameters are taken randomly to be complex with integer coefficients from 1 to K. Try:`): print(` RanLiPf(3,100,t,t,t^2); `): print(`RanLiPf(3,100,t,(t+1/t)/2,(t-1/t)/2/I);`): elif nargs=1 and args[1]=RanLiPrat then print(`RanLiPrat(k,K): a list of k random points with real rational integer, coordinates, whose`): print(`numerators and denominators are drawn from 10 to K+10`): print(`Try:`): print(`RanLiPrat(5,100);`): elif nargs=1 and args[1]=RanObjF then print(`RanObjF(P,k,K): given a list of points P, and a non-negative integer k`): print(`constructs a (not necessarily uniformly) random object of depth k`): print(`whose BOTH children are of depth k-1.`): print(`it keeps trying K times. It also returns the number of tries`): print(`if it can't do it in K tries, it returns FAIL`): print(`Try:`): print(`P:=RanLiP(4,40): RanObjF(P,9,100);`): elif nargs=1 and args[1]=RanObjF1 then print(`RanObjF1(P,k): given a list of points P, and a non-negative integer k`): print(`constructs a (not necessarily uniformly) random object of depth k`): print(`whose BOTH children are of depth k-1.`): print(`Try:`): print(`P:=RanLiP(4,40): RanObjF1(P,3);`): elif nargs=1 and args[1]=RanObjF4 then print(`RanObjF4(P,k,K): given a list of four points P`): print(`constructs a (not necessarily uniformly) random object of depth k`): print(`whose BOTH children are of depth k-1`): print(`when k>6, otherwise it could be any depth, except that, of course`): print(`one of the children must be of depth k-1`): print(`It keeps trying up to K times, or else returns FAIL`): print(`it also returns the number of tries `): print(`try:`): print(`P:=RanLiP(4,40): RanObjF4(P,9,100);`): elif nargs=1 and args[1]=RanObjsF4 then print(`RanObjsF4(P,k,K,R): given a list of points P, and a non-negative integer k`): print(`constructs a set of R (not necessarily uniformly) random object of depth k`): print(`whose BOTH children are of depth k-1.`): print(`when k>6, otherwise it could be any depth, except that, of course`): print(`one of the children must be of depth k-1`): print(`it keeps trying K times. It also returns the number of tries`): print(`if it can't do it in K tries, it returns FAIL`): print(`Try:`): print(`P:=RanLiP(4,40): RanObjsF4(P,9,100,10);`): elif nargs=1 and args[1]=RanObjF4a then print(`RanObjF4a(P,k): given a list of four points P`): print(`constructs a (not necessarily uniformly) random object of depth k`): print(`whose BOTH children are of depth k-1`): print(`when k>6, otherwise it could be any depth, except that, of course`): print(`one of the children must be of depth k-1`): print(`try:`): print(`P:=RanLiP(4,40): RanObjF4a(P,7);`): elif nargs=1 and args[1]=Reps then print(`Reps(S,n): given a set of combinatorial objects featuring {1,...n} finds`): print(`a class of representatives up to isomorphism`): elif nargs=1 and args[1]=Targem then print(`Targem(Li,P,Y,N): Given a geometrical object Li (a point or line), a letter P, and words Y (for line) and N (for point)`): print(`expresses it verbosely, try:`): print(`Targem({1,2},P,Line,Point);`): elif nargs=1 and args[1]=TtoC then print(`TtoC(Cr): inputs a creature in form of a tree, converts it to a circuit`): print(`Try: `): print(`TtoC({{1,2},{3,4}});`): elif nargs=1 and args[1]=Yesharim then print(`Yesharim(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the lines in the k-th generation, WITH NAMES, obtained by joining points`): print(`in earlier generations, (that are not already in earlier generations)`): print(`Try:`): print(`Yesharim([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=YesharimN then print(`YesharimN(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the lines in the k-th generation obtained by joining points`): print(`in earlier generation, (that are not already in earlier generations)`): print(`Without Names. For a version with Names do Yesharim(P,k)`): print(`Try:`): print(`YesharimN([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=YesharimPure then print(`YesharimPure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the lines in the k-th generation, WITH NAMES, obtained by joining points`): print(`in the previous generation of points (called geneartion k-1 of points), (that are not already in earlier generations)`): print(`Try:`): print(`YesharimPure([[1,4],[11,15],[105,23],[89,76]],1);`): elif nargs=1 and args[1]=YesharimNpure then print(`YesharimNpure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k`): print(`outputs all the lines in the k-th generation obtained by joining points`): print(`in generation k-1 of points , (that are not already in earlier generations)`): print(`Without Names. For a version with Names do Yesharim(P,k)`): print(`Try:`): print(`YesharimNpure([[1,4],[11,15],[105,23],[89,76]],1);`): else print(`There is no ezra for`, args ): fi: end: #The eq. of the line joining A and B Pt:=proc(A,B) : if normal(-B[1]*A[2]+A[1]*B[2])=0 then RETURN(FAIL): else [normal((A[2]-B[2])/(-B[1]*A[2]+A[1]*B[2])), normal((B[1]-A[1])/(-B[1]*A[2]+A[1]*B[2]))] fi: end: #The eq. of the line joining A and B Le:=proc(A,B): if normal(-B[1]*A[2]+A[1]*B[2])=0 then RETURN(FAIL): else [normal((A[2]-B[2])/(-B[1]*A[2]+A[1]*B[2])), normal((B[1]-A[1])/(-B[1]*A[2]+A[1]*B[2]))] fi: end: #NekudotN(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the points in the k-th generation obtained by intersecting lines #in earlier generation, that are not already in an earlier generation. #Try: #NekudotN([[1,4],[11,15],[105,23],[89,76]],1); NekudotN:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN(P): fi: lu:={seq(op(NekudotN(P,k1)),k1=0..k-1)}: gu:={seq(op(YesharimN(P,k1)),k1=0..k)}: mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Pt(gu[i],gu[j]): if kha<>FAIL then if not member(kha,lu) then mu:=mu union {kha} fi: fi: od: od: mu: end: #YesharimN(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the lines in the k-th generation obtained by joining points #in earlier generations, (that are not already in earlier generations) #Try: #YesharimN([1,,4],[11,15],[105,23],[89,76]],1); YesharimN:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({}): fi: lu:={seq(op(YesharimN(P,k1)),k1=0..k-1)}: gu:={seq(op(NekudotN(P,k1)),k1=0..k-1)}: mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Le(gu[i],gu[j]): if kha<>FAIL then if not member(kha,lu) then mu:=mu union {kha}: fi: fi: od: od: mu: end: #GenLiP(k,t,s): a generic list of k points phrased in terms of the indexed variables, t[1], ..., t[k], s[1], ..., s[k] #Try: #GenLiP(3,t,s); GenLiP:=proc(k,t,s) local i: [seq([t[i],s[i]],i=1..k)]: end: #RanLiP(k,K): a random list of k points (with integer complex coordinates taken randomly from 1..K #Try: #RanLiP(3,K); RanLiP:=proc(k,K) local i,ra,gu,P1: ra:=rand(1..K): gu:=[]: for i from 1 while nops(gu){}) then zub:=AreCollinear([L[i][2],L[j][2],L[k][2]]): if zub<>FAIL then gu:= gu union { [{L[i][1],L[j][1],L[k][1]},zub] }: fi: fi: od: od: od: gu: end: #Yesharim(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the lines, with Names, in the k-th generation obtained by joining points #in earlier generation, (that are not already in earlier generations) #Try: #The output is as set {[Name,Line]} #Yesharim([[1,4],[11,15],[105,23],[89,76]],1); Yesharim:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({}): fi: lu:={seq(op(Yesharim(P,k1)),k1=0..k-1)}: lu:={seq(lu[i][2],i=1..nops(lu))}: gu:={seq(op(Nekudot(P,k1)),k1=0..k-1)}: mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Le(gu[i][2],gu[j][2]): if not kha=FAIL then if not member(kha,lu) then mu:=mu union { [ {gu[i][1],gu[j][1]},kha ]}: fi: fi: od: od: mu: end: #Nekudot(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the points with Names in the k-th generation obtained by intersecting lines #in earlier generation, that are not already in an earlier generation. #the output is as a form {[Name,Pt]}: #Try: #Nekudot([[1,4],[11,15],[105,23],[89,76]],1); Nekudot:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({ seq([i,P[i]],i=1..nops(P))} ): fi: lu:={seq(op(Nekudot(P,k1)),k1=0..k-1)}: lu:={seq(lu[i][2],i=1..nops(lu))}: gu:={seq(op(Yesharim(P,k1)),k1=0..k)}: mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Pt(gu[i][2],gu[j][2]): if kha<>FAIL then if not member(kha,lu) then mu:=mu union {[{gu[i][1],gu[j][1]},kha]} fi: fi: od: od: mu: end: #ApplyPer(G,pi): applies the permutation pi to the object G, try #ApplyPer({{1,2},{3,4}},[2,1,4,3]); ApplyPer:=proc(G,pi) local i: subs({seq(i=pi[i],i=1..nops(pi))},G): end: #Reps(S,n): given a set of combinatorial objects featuring {1,...n} finds #a class of representative up to isomorphism Reps:=proc(S,n) local gu,mu,pi,S1,kha: mu:=permute(n): gu:={}: S1:=S: while S1<>{} do kha:=S1[1]: gu:=gu union {kha}: S1:=S1 minus {seq(ApplyPer(kha,pi),pi in mu)}: od: gu: end: #Esof(Li): given a set of pairs [Name,Objects], finds the set of distinct Objects, #and returns the list [Object,SetOfNamesWithThatObject]. For example, try: #Esof({[a,1],[b,1],[c,2],[d,3],[e,3]}; Esof:=proc(Li) local S,i,T,s,R,K,lu: S:={seq(Li[i][2],i=1..nops(Li))}: for s in S do T[s]:={}: od: for i from 1 to nops(Li) do T[Li[i][2]]:=T[Li[i][2]] union {Li[i][1]}: od: R:=max(seq(nops(T[s]), s in S)): for i from 1 to R do K[i]:=[]: od: for i from 1 to nops(S) do s:=S[i]: K[nops(T[s])]:=[op(K[nops(T[s])]),[s,T[s]]]: od: lu:=[]: for i from R by -1 to 1 do lu:=[op(lu),op(K[i])]: od: lu: end: #QuadM(s,t), all the miracles for a quadrilateral from second-generation points. #Try #QuadM(s,t); QuadM:=proc(s,t) local P,gu,mu,i,j: P:=GenLiP(4,t,s): gu:=Yesharim(P,3): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: mu:=[seq([mu[i][1],{seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))}],i=1..nops(mu))]: end: #Targem(Li,P,Y,N): Given a geometrical object Li (a point or line), a letter P, and words Y (for line) and N (for point) #expresses it verbosely, try: #Targem({1,2},P,Line,Point); Targem:=proc(Li,P,Y,N) local gu1,gu2: if type(Li,integer) then RETURN(P[Li]): fi: if nops(Li)<>2 then RETURN(FAIL): fi: if not (type(Li,list) or type(Li,set)) then RETURN(FAIL): fi: gu1:=Targem(Li[1],P,Y,N): if gu1=FAIL then RETURN(FAIL): fi: gu2:=Targem(Li[2],P,Y,N): if gu2=FAIL then RETURN(FAIL): fi: if IsPt(Li) then N(gu1,gu2): else Y(gu1,gu2): fi: end: #QuadMvWE(s,t,P), all the miracles for a quadrilateral from second-generation points. Verbose version #With Equations #Try #QuadMvWE(s,t,P); QuadMvWE:=proc(s,t,P) local mu,i,lu,t0,j,x,y: t0:=time(): mu:=QuadM(s,t): print(`An Amazing Theorem about a General Quadrilateral`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4] , `be ARBITRARY four points on the plane`): print(`The following is true`): lu:=mu[1][2]: print(`the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): for i from 2 to nops(mu) do lu:=mu[i][2]: print(``): print(`also the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): print(``): od: print(`Denoting the four point by`): print(seq(P[i]=[t[i],s[i]],i=1..4)): print( `The equations of the above lines are, respectively`): for i from 1 to nops(mu) do print(`The above`, i, `-th line is`): if denom(mu[i][1][1])=denom(mu[i][1][2]) then print(numer(mu[i][1][1])*x+numer(mu[i][1][2])*y+denom(mu[i][1][2])=0): else print(mu[i][1][1]*x+mu[i][1][1]*y+1=0): fi: od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #QuadMv(P), all the miracles for a quadrilateral from second-generation points. Verbose version #Try #QuadMv(P); QuadMv:=proc(P) local s,t,mu,i,lu,t0,j: t0:=time(): mu:=QuadM(s,t): print(`An Amazing Theorem about a General Quadrilateral`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4] , `be ARBITRARY four points on the plane`): print(`The following is true`): lu:=mu[1][2]: print(`the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): for i from 2 to nops(mu) do lu:=mu[i][2]: print(``): print(`also the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): print(``): od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #QuadMr(K), all the miracles for a quadrilateral from second-generation points., using random numeric points #with complex integers parameters from 1 to K #Try #QuadMr(K); QuadMr:=proc(K) local P,gu,mu,i,j: P:=RanLiP(4,K): gu:=Yesharim(P,3): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: Reps({seq({seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))},i=1..nops(mu))},4): end: #QuadMrV(P,K), all the miracles for a quadrilateral from second-generation points. Verbose version #using random points, with complex coordiates, drawn from integers from 1 to K #Try #QuadMrV(P,40); QuadMrV:=proc(P,K) local mu1,mu2,mu3,mu,i,lu,t0,j: t0:=time(): mu1:=QuadMr(K): mu2:=QuadMr(K): if mu1<>mu2 then RETURN(FAIL): fi: mu3:=QuadMr(K): if mu1<>mu3 then RETURN(FAIL): fi: mu:=mu1: print(`An Amazing Theorem about a General Quadrilateral`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4] , `be ARBITRARY four points on the plane`): print(`The following is true`): lu:=mu[1]: print(`the following three points are COLLINEAR`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: for i from 2 to nops(mu) do lu:=mu[i]: print(``): print(`also the following three points are COLLINEAR`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: print(``): od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #PascalM(t), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio. #It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2 #where a parametric point is [t[i],t[i]^2] #Try #PascalM(t); PascalM:=proc(t) local P,gu,mu,i,j,T,mu11,mu1: P:=GenLiPf(6,t,t,t^2): gu:=Yesharim(P,2): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: mu:=[seq([mu[i][1],{seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))}],i=1..nops(mu))]: for i from 1 to nops(mu) do T[mu[i][2]]:=mu[i][1]: od: mu1:=Reps({seq(mu[i][2],i=1..nops(mu))},6): {seq([T[mu11],mu11],mu11 in mu1)}: end: #PascalMv(P), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio. #It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2 #where a parametric point is [t[i],t[i]^2]. Verbose version #Try #PascalMv(P); PascalMv:=proc(P) local t,mu,i,lu,t0,j: t0:=time(): mu:=PascalM(P,t): print(`An Amazing Theorem about an Inscribed Hexagon in Conic`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4], P[5], P[6] ,`be ARBITRARY six points lying on a conic section`): print(`The following is true`): lu:=mu[1][2]: print(`the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): for i from 2 to nops(mu) do lu:=mu[i][2]: print(``): print(`also the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): print(``): od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #PascalMvWE(P), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio. #It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2 #where a parametric point is [t[i],t[i]^2]. Verbose version #With Equations #Try #PascalMvWE(P); PascalMvWE:=proc(P) local t,mu,i,lu,t0,j: t0:=time(): mu:=PascalM(t): print(`An Amazing Theorem about an Inscribed Hexagon in Conic`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4], P[5], P[6] ,`be ARBITRARY six points lying on a conic section`): print(`The following is true`): lu:=mu[1][2]: print(`the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): for i from 2 to nops(mu) do lu:=mu[i][2]: print(``): print(`also the following three points are COLLINEAR`): print(seq(Targem(lu[j],P,Line,Point),j=1..nops(lu))): print(``): od: print(`Denoting the six points (assumed to lie on the parabola y=x^2) by`): print(seq(P[i]=[t[i],t[i]^2],i=1..6)): print(`The equations of the above lines are, respectively`): for i from 1 to nops(mu) do print(`The above`, i, `-th line is`): if denom(mu[i][1][1])=denom(mu[i][1][2]) then print(numer(mu[i][1][1])*x+numer(mu[i][1][2])*y+denom(mu[i][1][2])=0): else print(mu[i][1][1]*x+mu[i][1][1]*y+1=0): fi: od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #PascalMr(K), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio. #It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2 #where a parametric point it [t[i],t[i]^2] #using random points with complex integer parameters from 1 to K #Try #PascalMr(40); PascalMr:=proc(K) local t,P,gu,mu,i,j,mu11,mu1: P:=RanLiPf(6,K,t,t,t^2): gu:=Yesharim(P,2): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: mu:=[seq([mu[i][1],{seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))}],i=1..nops(mu))]: Reps({seq(mu[i][2],i=1..nops(mu))},6): end: #PascalMrV(P,K), all the miracles for an inscribed (in a conic) hexagon, rediscovering Pascal's theorem ab initio. #It also gives the equations of the miraculous lines in terms of t[1], ..., t[6] if it is no a parabola y=x^2 #where a parametric point is [t[i],t[i]^2]. Verbose version #using random points from 1 to K #Try #PascalMrV(P,50); PascalMrV:=proc(P,K) local mu1,mu2,mu3,mu, i,lu,t0,j: t0:=time(): mu1:=PascalMr(K): mu2:=PascalMr(K): if mu1<>mu2 then RETURN(FAIL): fi: mu3:=PascalMr(K): if mu1<>mu3 then RETURN(FAIL): fi: mu:=mu1: print(`An Amazing Theorem about an Inscribed Hexagon in Conic`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4], P[5], P[6] ,`be ARBITRARY six points lying on a conic section`): print(`The following is true`): lu:=mu[1]: print(`the following three points are COLLINEAR`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: print(`--------------------------------`): for i from 2 to nops(mu) do lu:=mu[i]: print(``): print(`also the following three points are COLLINEAR`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: print(``): od: print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #CS(Li): Given a list of five points, finds the unique conic section passing through them #Try: #CS([[1,3],[6,4],[6,1],[11,13],[5,2]]); CS:=proc(Li) local eq,var,P,x,y,A1,B1,C1,D1,E1,i: if nops(Li)<>5 then RETURN(FAIL): fi: var:={A1,B1,C1,D1,E1}: P:=A1*x^2+B1*x*y+C1*y^2+D1*x+E1*y+1: eq:={seq(expand(subs({x=Li[i][1],y=Li[i][2]},P)),i=1..nops(Li))}: var:=solve(eq,var): if var=NULL then RETURN(FAIL): else expand(subs(var,P)): fi: end: #PentMr(K), all the miracles for a #pentagon from second-generation lines, using random numeric points #with complex integers parameters from 1 to K #Try #PentMr(K); PentMr:=proc(K) local P,gu,mu,i,j: P:=RanLiP(5,K): gu:=Nekudot(P,2): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: mu:=[seq([mu[i][1],{seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))}],i=1..nops(mu))]: Reps({seq(mu[i][2],i=1..nops(mu))},5): end: #PentMrPure(K), all the miracles for a #pentagon from second-generation lines, using random numeric points #with complex integers parameters from 1 to K #Try #PentMrPure(100); PentMrPure:=proc(K) local P,gu,mu,i,j: P:=RanLiP(5,K): gu:=NekudotPure(P,2): mu:=Esof(gu): for i from 1 to nops(mu) while nops(mu[i][2])>1 do od: mu:=[op(1..i-1,mu)]: mu:=[seq([mu[i][1],{seq(op(mu[i][2][j]),j=1..nops(mu[i][2]))}],i=1..nops(mu))]: Reps({seq(mu[i][2],i=1..nops(mu))},5): end: #PentMrV(P,K), all the miracles for a #Pentagon from second-generation lines Verbose version #using random points, with complex coordiates, drawn from integers from 1 to K #Try #PentMrV(P,40); PentMrV:=proc(P,K) local mu1,mu2,mu3,mu,i,lu,t0,j: t0:=time(): mu1:=PentMr(K): mu2:=PentMr(K): if mu1<>mu2 then RETURN(FAIL): fi: mu3:=PentMr(K): if mu1<>mu3 then RETURN(FAIL): fi: mu:=mu1: print(`An Amazing Theorem about a General Pentagon`): print(``): print(`By Shalosh B. Ekhad `): print(``): print(`For any two points,P,Q let, Line(P,Q) be the line joining P and Q`): print(`For any two lines L and N let, Point(L,N) be the point of intersection of L and N`): print(``): print(`Theorem: Let`, P[1],P[2],P[3],P[4],P[5] , `be ARBITRARY five points on the plane`): print(`The following is true`): lu:=mu[1]: print(`the following three lines are Concurrent`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: print(`----------------------------`): for i from 2 to nops(mu) do lu:=mu[i]: print(``): print(`also the following three lines are Concurrent`): for j from 1 to nops(lu) do print(Targem(lu[j],P,Line,Point)): od: print(`----------------------------`): print(``): od: print(``): print(`This ends this article, that took`, time()-t0, `seconds to produce.`): end: #IsPt(A): given a geometrical object decides wether it is #a point or not (or neither, then it returns FAIL) #Try: #IsPt({1,2}); IsPt:=proc(L) : if not ((type(L,set) and nops(L)=2) or type(L,integer)) then RETURN(FAIL): fi: if type(L,integer) then RETURN(true): fi: if IsPt(L[1])=FAIL or IsPt(L[2])=FAIL then RETURN(FAIL): fi: if IsPt(L[1]) and IsPt(L[2]) then false: elif (not IsPt(L[1]) ) and (not IsPt(L[2])) then true: else FAIL: fi: end: #Omek(A): given a geometrical object finds its depth #Try: #Omek({1,2}); Omek:=proc(L): if not ((type(L,set) and nops(L)=2) or type(L,integer)) then RETURN(FAIL): fi: if type(L,integer) then RETURN(0): fi: if IsPt(L[1])=FAIL or IsPt(L[2])=FAIL then RETURN(FAIL): fi: max(Omek(L[1]),Omek(L[2]))+1: end: #RanObjF1(P,k): given a list of points P, and a non-negative integer k #constructs a (not necessarily uniformly) random object of depth k #whose BOTH children are of depth k-1 #try: #P:=RanLiP(4,40): RanObjF(P,3); RanObjF1:=proc(P,k) local n,P1,P2,r,s, mu,Pnew,i: n:=nops(P): if k=0 then r:=rand(1..nops(P))(): RETURN([r,P[r]]): fi: if k=1 then r:=rand(1..n)(): Pnew:={seq(i,i=1..n)} minus {r}: s:=Pnew[rand(1..n-1)()]: RETURN([{r,s},Pt(P[r],P[s])]): fi: P1:=RanObjF1(P,k-1): if P1=FAIL then RETURN(FAIL): fi: P2:=RanObjF1(P,k-1): if P2=FAIL then RETURN(FAIL): fi: if P1=P2 then RETURN(FAIL): else mu:=Pt(P1[2],P2[2]): if mu=FAIL then RETURN(FAIL): else RETURN([{P1[1],P2[1]},Pt(P1[2],P2[2])]): fi: fi: end: #RanObjF(P,k,K): given a list of points P, and a non-negative integer k #constructs a (not necessarily uniformly) random object of depth k up to K tries #whose BOTH children are of depth k-1 #it also returns the number of tries #try: #P:=RanLiP(4,40,100): RanObjF(P,3); RanObjF:=proc(P,k,K) local gu,i: for i from 1 to K do gu:=RanObjF1(P,k): if gu<>FAIL then RETURN(gu,i): fi: od: FAIL: end: #PopExp(n,K,R): starting with n points (taken randomly with complex coordinates with parameters from 1 to K #finds the cardinalities of successive generations, up to NekudotN(P,R) #Try: #PopExp(4,100,2); PopExp:=proc(n,K,R) local gu,P,i: P:=RanLiP(n,K): gu:=[]: for i from 0 to R do gu:=[op(gu), nops(NekudotN(P,i))]: gu:=[op(gu), nops(YesharimN(P,i+1))]: od: gu: end: #RanObjF4a(P,k): given a list of four points P #constructs a (not necessarily uniformly) random object of depth k #whose BOTH children are of depth k-1 #try: #P:=RanLiP(4,40): RanObjF4a(P); RanObjF4a:=proc(P,k) local P1,P2,mu, gu,lu: if nops(P)<>4 then RETURN(FAIL): fi: if k<=6 then if k mod 2=0 then gu:=Nekudot(P,k/2): else gu:=Yesharim(P,(k+1)/2): fi: mu:=Esof(gu): lu:=mu[rand(1..nops(mu))()]: RETURN([lu[2][1],lu[1]]): fi: P1:=RanObjF4a(P,k-1): if P1=FAIL then RETURN(FAIL): fi: P2:=RanObjF4a(P,k-1): if P2=FAIL then RETURN(FAIL): fi: if P1=P2 then RETURN(FAIL): else mu:=Pt(P1[2],P2[2]): if mu=FAIL then RETURN(FAIL): else RETURN([{P1[1],P2[1]},Pt(P1[2],P2[2])]): fi: fi: end: #RanObjF4(P,k,K): given a list of four points P, #and a non-negative integer k #constructs a (not necessarily uniformly) random object of depth k up to K tries #whose BOTH children are of depth k-1 (except for k<=6) #it also returns the number of tries #try: #P:=RanLiP(4,40): RanObjF4(P,8,10); RanObjF4:=proc(P,k,K) local gu,i: if nops(P)<>4 then RETURN(FAIL): fi: for i from 1 to K do gu:=RanObjF4a(P,k): if gu<>FAIL then RETURN(gu,i): fi: od: FAIL: end: #RanObjsF4(P,k,K,R): given a list of four points P, #and a non-negative integer k #constructs (not necessarily uniformly) a set of R random objects of depth k up to K tries #whose BOTH children are of depth k-1 (except for k<=6) #it also returns the number of tries #try: #P:=RanLiP(4,40): RanObjsF4(P,9,10,50); RanObjsF4:=proc(P,k,K,R) local gu,i,mu: gu:={}: for i from 1 to R do mu:=RanObjF4(P,k,K): if mu<>FAIL then gu:=gu union {mu[1]}: fi: od: gu: end: #EnumSeq(k,N): the first N terms of the enumeration sequence number of points (lines) in i-th generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points. Using symbolic generic points #Try: #EnumSeq(4,2); EnumSeq:=proc(k,N) local P,t,s,gu,i: P:=GenLiP(k,t,s): gu:=[]: for i from 0 to N do if i mod 2=0 then gu:=[op(gu),nops(NekudotN(P,i/2))]: else gu:=[op(gu),nops(YesharimN(P,(i-1)/2+1))]: fi: od: gu: end: #EnumSeqPure(k,N): the first N terms of the enumeration sequence number of points (lines) in i-th generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points. Using symbolic generic points #Try: #EnumSeqPure(4,2); EnumSeqPure:=proc(k,N) local P,t,s,gu,i: P:=GenLiP(k,t,s): gu:=[]: for i from 0 to N do if i mod 2=0 then gu:=[op(gu),nops(NekudotNpure(P,i/2))]: else gu:=[op(gu),nops(YesharimNpure(P,(i-1)/2+1))]: fi: od: gu: end: #EnumSeqR1(k,N,K): the first N terms of the enumeration sequence number of points (lines) in i-th generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points #Using ONE random choice of complex points taken from 1 to K #Try: #EnumSeqR1(4,2,100); EnumSeqR1:=proc(k,N,K) local P,t,s,gu,i: P:=RanLiP(k,K): gu:=[]: for i from 0 to N do if i mod 2=0 then gu:=[op(gu),nops(NekudotN(P,i/2))]: else gu:=[op(gu),nops(YesharimN(P,(i-1)/2+1))]: fi: od: gu: end: #EnumSeqR(k,N,K,r): the first N terms of the enumeration sequence number of points (lines) in i-th generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points #Using r random choices of starting points with complex coordinates taken from 1 to K #It returns FAIL if their is even one disagreement. #Try: #EnumSeqR(4,2,100,10); EnumSeqR:=proc(k,N,K,r) local gu,i: gu:={}: for i from 1 to r do gu:=gu union { EnumSeqR1(k,N,K)}: od: if nops(gu)<>1 then lprint(gu): RETURN(FAIL): else RETURN(gu[1]): fi: end: #RanLiPrat(k,K): a random list of k points (with real rational coordinates taken randomly from 1..K #Try: #RanLiPrat(3,K); RanLiPrat:=proc(k,K) local i,ra,gu,P1: ra:=rand(1001..K+1001): gu:=[]: for i from 1 while nops(gu)FAIL then if not member(kha,lu) then mu:=mu union {kha} fi: fi: od: od: mu: end: #YesharimNpure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the lines in the k-th generation obtained by joining points #in the previous generation, (that are not already in earlier generations) #Try: #YesharimNpure([1,,4],[11,15],[105,23],[89,76]],1); YesharimNpure:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({}): fi: lu:={seq(op(YesharimN(P,k1)),k1=0..k-1)}: gu:=NekudotN(P,k-1): mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Le(gu[i],gu[j]): if kha<>FAIL then if not member(kha,lu) then mu:=mu union {kha}: fi: fi: od: od: mu: end: #YesharimPure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the lines, with Names, in the k-th generation obtained by joining points #in the previous generation, (that are not already in earlier generations) #Try: #The output is as set {[Name,Line]} #YesharimPure([[1,4],[11,15],[105,23],[89,76]],1); YesharimPure:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({}): fi: lu:={seq(op(YesharimPure(P,k1)),k1=0..k-1)}: lu:={seq(lu[i][2],i=1..nops(lu))}: gu:=NekudotPure(P,k-1): mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Le(gu[i][2],gu[j][2]): if not kha=FAIL then if not member(kha,lu) then mu:=mu union { [ {gu[i][1],gu[j][1]},kha ]}: fi: fi: od: od: mu: end: #NekudotPure(P,k): inputs a list of Adam-Eve-points, P, and a positive integer k #outputs all the points with Names in the k-th generation obtained by intersecting lines #in the previous generation, that are not already in an earlier generation. #the output is as a form {[Name,Pt]}: #Try: #NekudotPure([[1,4],[11,15],[105,23],[89,76]],1); NekudotPure:=proc(P,k) local gu,lu,mu,kha,k1,i,j: option remember: if k=0 then RETURN({ seq([i,P[i]],i=1..nops(P))} ): fi: lu:={seq(op(NekudotPure(P,k1)),k1=0..k-1)}: lu:={seq(lu[i][2],i=1..nops(lu))}: gu:=YesharimPure(P,k): mu:={}: for i from 1 to nops(gu) do for j from i+1 to nops(gu) do kha:=Pt(gu[i][2],gu[j][2]): if kha<>FAIL then if not member(kha,lu) then mu:=mu union {[{gu[i][1],gu[j][1]},kha]} fi: fi: od: od: mu: end: #EvalCr(C,LiP): evaluates the creature C consisisting of the set of points LiP #Try: #EvalCr({1,2},[[2,3],[6,11]]); EvalCr:=proc(C,LiP) local P1,P2 : if not type(C,set) then RETURN(LiP[C]): fi: P1:=EvalCr(C[1],LiP): if P1=FAIL then RETURN(FAIL): fi: P2:=EvalCr(C[2],LiP): if P2=FAIL then RETURN(FAIL): fi: if IsPt(C) then Pt(P1,P2 ): else Le(P1,P2): fi: end: #EnumSeqR1pure(k,N,K): the first N terms of the enumeration sequence number of points (lines) in i-th PURE generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points #Using ONE random choice of complex points taken from 1 to K #Try: #EnumSeqR1pure(4,2,100); EnumSeqR1pure:=proc(k,N,K) local P,t,s,gu,i: P:=RanLiP(k,K): gu:=[]: for i from 0 to N do if i mod 2=0 then gu:=[op(gu),nops(NekudotNpure(P,i/2))]: else gu:=[op(gu),nops(YesharimNpure(P,(i-1)/2+1))]: fi: od: gu: end: #EnumSeqRpure(k,N,K,r): the first N terms of the enumeration sequence number of points (lines) in i-th PURE generation #starting with k distinct, general points, at generation 0 #and then iterating taking all possible lines and all possible points #Using r random choices of starting points with complex coordinates taken from 1 to K #It returns FAIL if their is even one disagreement. #Try: #EnumSeqRpure(4,2,100,10); EnumSeqRpure:=proc(k,N,K,r) local gu,i: gu:={}: for i from 1 to r do gu:=gu union { EnumSeqR1pure(k,N,K)}: od: if nops(gu)<>1 then lprint(gu): RETURN(FAIL): else RETURN(gu[1]): fi: end: #DrawPt(A,NA): Given a point A, and a name NA #puts the label NA at A DrawPt:=proc(A,NA) local d: d:=textplot([A[1],A[2],NA],numpoints=3000): #d:=textplot([A[1],A[2],NA],axes=none,numpoints=3000): d:=d,plot({A},style=point, symbol=circle): end: #DrawPtNL(A,NA): Given a point A, and a name NA #puts the label NA at A DrawPtNL:=proc(A,NA) local d: plot({A},style=point): end: #DrawLeSegment(A,B,NA,NB): Given points A,B, and names #NA,NB draws the line segment AB with the labels NA,NB DrawLeSegment:=proc(A,B,NA,NB) local d: d:=plot([A,B],axes=none,numpoints=3000): d:=d,textplot([A[1],A[2],NA]),textplot([B[1],B[2],NB]): d: end: #DrawLe(A,B,k): draws the line from point #A to point B DrawLe:=proc(A,B,k) local d,A1,B1: A1:=[(k+1)*A[1]-k*B[1],(k+1)*A[2]-k*B[2]]: B1:=[(k+1)*B[1]-k*A[1],(k+1)*B[2]-k*A[2]]: d:=plot([A1,B1],axes=none): d:=d,plot({A,B},style=point,symbol=circle): d: end: #DrawObj1(LiP,C,P,k): given a list of points LiP, and a creature C draws it without labels #the lines stretch from x=-K to x=K P is a letter #Try: #DrawObj1([[1,2],[4,5]],{1,2},P,4); DrawObj1:=proc(LiP,C,P,k) local d1,d2,d,Yash,Nek,Pt1,Pt2: if not type(C,set) then d:=DrawPt(LiP[C],P[C]): RETURN(d): fi: d1:=DrawObj1(LiP,C[1],P,k): d2:=DrawObj1(LiP,C[2],P,k): if d1=FAIL or d2=FAIL then RETURN(FAIL): fi: if not IsPt(C) then Pt1:=EvalCr(C[1],LiP): if Pt1=FAIL then RETURN(FAIL): fi: Pt2:=EvalCr(C[2],LiP): if Pt2=FAIL then RETURN(FAIL): fi: Yash:=DrawLe(Pt1,Pt2,k): if Yash=FAIL then RETURN(FAIL): fi: d:=d1,d2,Yash: RETURN(d): else Nek:=EvalCr(C,LiP): if Nek=FAIL then RETURN(FAIL): fi: d:=d1,d2,plot({Nek},axes=none, style=point,symbol=circle): RETURN(d): fi: end: #DrawObj(LiP,C,P,k): given a list of points LiP, and a creature C draws it without labels #Try: #DrawObj([[1,2],[4,5]],{1,2},P,4); DrawObj:=proc(LiP,C,P,k) local gu,Pt1: gu:=DrawObj1(LiP,C,P,k): if gu=FAIL then RETURN(FAIL): fi: Pt1:=EvalCr(C,LiP): if Pt1=FAIL then RETURN(FAIL): fi: if IsPt(C) then gu:=gu,plot({Pt1},style=point, color=black): fi: display(gu): end: #Nodes1(Cr): Inputs a creature, Cr (i.e. a tree) outputs all its leaves, followed by its interior vertices, #Try: #Nodes1({{1,2},{3,4}}); Nodes1:=proc(Cr) local gu1,gu2: if not type(Cr,set) then RETURN([{Cr},{}]): fi: gu1:=Nodes1(Cr[1]): gu2:=Nodes1(Cr[2]): [gu1[1] union gu2[1], gu1[2] union gu2[2] union {Cr}]: end: #TtoC1(Cr): inputs a creature in form of a tree, converts it to a circuit with long names #Try: #TtoC1({{1,2},{3,4}}); TtoC1:=proc(Cr) local gu1,gu2: if not type(Cr,set) then RETURN({}): fi: gu1:=TtoC1(Cr[1]): gu2:=TtoC1(Cr[2]): gu1 union gu2 union {[Cr,Cr]}: end: #TtoC(Cr): inputs a creature in form of a tree, converts it to a circuit #Try: #TtoC({{1,2},{3,4}}); TtoC:=proc(Cr) local gu,L,V,Ta,k,i,mu,Sa,mu1: gu:=Nodes1(Cr): L:=gu[1]: V:=gu[2]: k:=nops(L): for i from 1 to k do Ta[i]:=i: od: for i from 1 to nops(V) do Ta[V[i]]:=i+k: od: mu:=TtoC1(Cr): for mu1 in mu do Sa[Ta[mu1[1]]]:={Ta[mu1[2][1]],Ta[mu1[2][2]]}: od: [seq([i],i=1..k),seq(Sa[i+k],i=1..nops(V)) ]: end: #EvalCu(LiP,C,v): given a list of points and a circuit C, and vertex i, evalutes it #Try: #EvalCu([[1,2],[4,5]],[[1],[2],{1,2}],3); EvalCu:=proc(LiP,C,v) local i,k,mu,lu1,lu2: option remember: k:=nops(LiP): for i from 1 to nops(C) while nops(C[i])=1 do od: if i-1<>k then RETURN(FAIL): fi: if not (type(v, integer) and v>0 and v<=nops(C)) then RETURN(FAIL): fi: if v<=k then RETURN(LiP[v]): else mu:=C[v]: lu1:=EvalCu(LiP,C,mu[1]): if lu1=FAIL then RETURN(FAIL): fi: lu2:=EvalCu(LiP,C,mu[2]): if lu2=FAIL then RETURN(FAIL): fi: RETURN(Pt(lu1,lu2)): fi: end: #IsPtCu(C,v): Given a circuit C, and a vertex v, decides whether it is a point #Try: #IsPtCu([[1],[2],{1,2}],3); IsPtCu:=proc(C,v) local lu1,lu2: option rememember: if nops(C[v])=1 then RETURN(true): fi: lu1:=IsPtCu(C,C[v][1]): lu2:=IsPtCu(C,C[v][2]): if lu1<>lu2 then print(`Something terrible happened, a point had sex with a line!`): RETURN(FAIL): fi: not lu1: end: #Ge(LiP,C): the full story of the Genealogy of the last memeber of the circuit C #starting with the list of points LiP, try: #Ge([[a,b],[c,d]],[[1],[2],{1,2}]); Ge:=proc(LiP,C) local k,Adam,i,mu,x,y,t0: t0:=time(): k:=nops(LiP): mu:=EvalCu(LiP,C,nops(C)): if IsPt(C,nops(C)) then print(`The Genealogy of the point (man) Mr. `, nops(C)): print(`who happens to be `, mu): else print(`The Genealogy of the line (woman) Ms. `, nops(C)): print(`who happens to be `, mu[1]*x+mu[2]*y+1=0): fi: print(` By Shalosh B. Ekhad `): print(`At the Sixth day of Creation, God created`, k, `men (alias points) , whose names, and identity are as follows.`): for i from 1 to k do print(Adam[i], `alias, Mr.`, i, `who happens to be the point`, LiP[i]): od: for i from k+1 to nops(C)-1 do mu:=EvalCu(LiP,C,i): if IsPtCu(C,i) then print(`and it came to pass that Ms.`, C[i][1], ` knew Ms. `, C[i][2], `and together they begat Mr.`, i): print(`who happens to be the point`, mu): else print(`and it came to pass that Mr.`, C[i][1], ` knew Mr. `, C[i][2], `and together they begat Ms.`, i): print(`who happens to be the line`, mu[1]*x+mu[2]*y+1): fi: od: for i from nops(C) to nops(C) do mu:=EvalCu(LiP,C,i): if IsPtCu(C,i) then print(`and FINALLY, it came to pass that Ms.`, C[i][1], ` knew Ms. `, C[i][2], `and together they begat our hero, Mr.`, i): print(`who happens to be the point`, mu): else print(`and FINALLY, it came to pass that Mr.`, C[i][1], ` knew Mr. `, C[i][2], `and together they begat our hero, Ms.`, i): print(`who happens to be the line`, mu[1]*x+mu[2]*y+1): fi: od: print(`This ends this fascinating genealogy, that took`, time()-t0, `seconds to generate. `): end: #DrawObjNL(LiP,C,P,k): given a list of points LiP, and a creature C draws it without labels #Try: #DrawObjNL([[1,2],[4,5]],{1,2},P,4); DrawObjNL:=proc(LiP,C,P,k) local gu,Pt1: gu:=DrawObj1NL(LiP,C,P,k): if gu=FAIL then RETURN(FAIL): fi: Pt1:=EvalCr(C,LiP): if Pt1=FAIL then RETURN(FAIL): fi: if IsPt(C) then gu:=gu,plot({Pt1},style=point, color=black): fi: display(gu): end: #DrawObj1NL(LiP,C,P,k): given a list of points LiP, and a creature C draws it without labels #the lines stretch from x=-K to x=K P is a letter #Try: #DrawObj1NL([[1,2],[4,5]],{1,2},P,4); DrawObj1NL:=proc(LiP,C,P,k) local d1,d2,d,Yash,Nek,Pt1,Pt2: if not type(C,set) then d:=DrawPtNL(LiP[C],P[C]): RETURN(d): fi: d1:=DrawObj1NL(LiP,C[1],P,k): d2:=DrawObj1NL(LiP,C[2],P,k): if d1=FAIL or d2=FAIL then RETURN(FAIL): fi: if not IsPt(C) then Pt1:=EvalCr(C[1],LiP): if Pt1=FAIL then RETURN(FAIL): fi: Pt2:=EvalCr(C[2],LiP): if Pt2=FAIL then RETURN(FAIL): fi: Yash:=DrawLe(Pt1,Pt2,k): if Yash=FAIL then RETURN(FAIL): fi: d:=d1,d2,Yash: RETURN(d): else Nek:=EvalCr(C,LiP): if Nek=FAIL then RETURN(FAIL): fi: d:=d1,d2,plot({Nek},axes=none, style=point,symbol=circle): RETURN(d): fi: end: