Giter VIP home page Giter VIP logo

form's People

Contributors

alexmyczko avatar benruijl avatar fchapoton avatar jodavies avatar magv avatar mreininghaus avatar rldelgado avatar spj101 avatar tueda avatar vermaseren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

form's Issues

Bug with function replacement

The following minimal code works with the released 4.1 version on github and older FORM version, but not with 4.1 binaries on the FORM webpage and the current master:

Symbols a, b; 
Functions fun, nDUMMY1, nDUMMY2;
Local expr= fun(a)*fun(b) ;
Id nDUMMY1?(?args1) * nDUMMY2?(?args2) = 1;
.sort
Print;
.end

Error message:

TFORM 4.1 (Jan 13 2014) 64-bits 0 workers        Run: Wed Mar 19 14:07:27 2014
    Symbols a, b; 
    Functions fun, nDUMMY1, nDUMMY2;
    Local expr= fun(a)*fun(b) ;
    Id nDUMMY1?(?args1) * nDUMMY2?(?args2) = 1;
Program terminating in thread 0 at replacefuncs.frm Line 4 --> 

The bug was introduced by the commit d0a46ff (found out by using git bisect).

FactDollar still broken

In the following example, $a = 1+x-y is factorized as $a[1] = -1 and $a[2] = 1+x-y. The overall sign is wrong.

S x,y;
#$a = 1+x-y;
#factdollar $a
#$b = 1
  #do i=1,`$a[0]'
    * (`$a[`i']')
  #enddo
;
#$c = $a - $b;  * should be 0
#message $a=`$a'
#do i=0,`$a[0]'
  #message $a[`i']=`$a[`i']'
#enddo
#message $b=`$b'
#message $c=`$c'
.end
~~~$a=1-y+x
~~~$a[0]=2
~~~$a[1]=-1
~~~$a[2]=x-y+1
~~~$b=-1+y-x
~~~$c=2-2*y+2*x

[parform] RHS expressions in Fill or FillExpression doesn't work

[Update] FillExpression was implemented.

References to expressions in tables doesn't trigger any broadcasting of RHS expressions. (Use of expressions in Fill statements is not recommended and FORM warns.) For example, for an example in Fill statement in the manual,

Table B(1:1);
Local dummy = 1;
.sort
Fill B(1) = dummy;
.sort
Local F = B(1);
Print;
.sort
Drop;
.sort
Local dummy = 2;
.sort
Local F = B(1);
Print;
.end

ParFORM prints F = 0, while the sequential FORM prints F = 1 for the first Print statement and F = 2 for the second.

FillExpression has the same problem that RHS expressions are not broadcast when the master and workers try to fill tables. So, the tables on the workers differ from that on the master and cause troubles. For the following program:

CTable tab(1:2);
S x;
CF f;
L F = <f(1)*x^1>+...+<f(2)*x^2>;
B x;
P;
.sort
FillExpression tab = F(x);
L F1 = tab(1);
L F2 = tab(2);
PrintTable tab;
P;
.end

ParFORM freezes with an error "Element in table is undefined tab(1)".

Substitutions just after putinside/antiputinside may fail

Just after putinside, some of substitutions for the generated functions don't match:

S x;
CF f;
L F1 = 1+x+x^2;
L F2 =-1-x-x^2;
putinside f, x;
*argument; endargument;  * <-- (1)
id f( 1)   = 0;
id f(-1)   = 0;
id f( x)   = 0;
id f(-x)   = 0;
id f( x^2) = 0;
id f(-x^2) = 0;
P;
.end

which gives

   F1 =
      f(1) + f(x);

   F2 =
      f( - 1);

(F1 and F2 are expected zero.)

Enabling line (1) gives the expected result. Maybe some dirty flag problems?

The same thing occurs for antiputinside:

S x;
CF f;
L F1 = 1+x+x^2;
L F2 =-1-x-x^2;
antiputinside f, x;
*argument; endargument;  * <-- (1)
id f( 1) = 0;
id f(-1) = 0;
P;
.end

which gives

   F1 =
      f(1) + f(1)*x + f(1)*x^2;

   F2 =
      f( - 1) + f( - 1)*x + f( - 1)*x^2;

Factorize is much slower than FactArg/FactDollar

Separated from #42.

Test program: https://gist.githubusercontent.com/tueda/5f83e562854158b5a62f/raw/test1.frm

The slowness comes from the fact that in factorization of expressions the contents are not extracted before calling the general factorization routine. It needs some work:

  • We need to interfere in data read from an expression in poly_factorize_expression() before calling polyfact::factorize().
  • How should we handle expressions that have already been factorized (but modified by, e.g., substitutions)? We won't use the simplest solution: unfactorize -> factorize (expected to be slow).

Memory error on dollar matching

The following form program gives memory errors and coredumps:

#-
#-
CFunction TOPO,topo;
CFunction color;
Symbol M1,M2,x,cOlNA,cOlNR,ca,cf,nf,[dabc^2/n],[d4RR/n],[d4RA/n],[d4AA/n];

L   Diagrams=
      +topo(M1)*color(24*[d4RR/n]*cOlNA*cOlNR^-1+12*ca*[dabc^2/n]+
      ca^2*cf*nf)
      +topo(M2)*color(24*[d4RA/n]*cOlNA*cOlNR^-1+24*cf^4-72*ca*cf^3
      +66*ca^2*cf^2-19*ca^3*cf)
;

.sort

   id  topo(x?$topo) = 1;
   id  color(x?$color) = 1;

   $color = $color * topo($topo);
.end

Note that the terms inside color() are quite specific: if you remove one, the program passes.

Here is the valgrind log:

==26512== Invalid write of size 4
==26512==    at 0x44ABD7: WildDollars (dollar.c:970)
==26512==    by 0x4A2322: TestMatch (pattern.c:342)
==26512==    by 0x4C3CC9: Generator (proces.c:3523)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512==  Address 0x627dd48 is 0 bytes after a block of size 200 alloc'd
==26512==    at 0x4C29E6F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26512==    by 0x52C941: Malloc1 (tools.c:2205)
==26512==    by 0x4FAD7F: EndSort (sort.c:696)
==26512==    by 0x449658: AssignDollar (dollar.c:425)
==26512==    by 0x4C2FB8: Generator (proces.c:3371)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512== 
==26512== Invalid read of size 4
==26512==    at 0x44C053: DolToTerms (dollar.c:1445)
==26512==    by 0x4C4190: Generator (proces.c:3605)
==26512==    by 0x4495FE: AssignDollar (dollar.c:416)
==26512==    by 0x4C2FB8: Generator (proces.c:3371)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512==  Address 0x627dd48 is 0 bytes after a block of size 200 alloc'd
==26512==    at 0x4C29E6F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26512==    by 0x52C941: Malloc1 (tools.c:2205)
==26512==    by 0x4FAD7F: EndSort (sort.c:696)
==26512==    by 0x449658: AssignDollar (dollar.c:425)
==26512==    by 0x4C2FB8: Generator (proces.c:3371)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512== 
==26512== Invalid read of size 4
==26512==    at 0x44C39B: DolToTerms (dollar.c:1511)
==26512==    by 0x4C4190: Generator (proces.c:3605)
==26512==    by 0x4495FE: AssignDollar (dollar.c:416)
==26512==    by 0x4C2FB8: Generator (proces.c:3371)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512==  Address 0x627dd48 is 0 bytes after a block of size 200 alloc'd
==26512==    at 0x4C29E6F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26512==    by 0x52C941: Malloc1 (tools.c:2205)
==26512==    by 0x4FAD7F: EndSort (sort.c:696)
==26512==    by 0x449658: AssignDollar (dollar.c:425)
==26512==    by 0x4C2FB8: Generator (proces.c:3371)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4C46AA: Generator (proces.c:3760)
==26512==    by 0x4BA51B: Processor (proces.c:392)
==26512==    by 0x45581E: DoExecute (execute.c:800)
==26512==    by 0x47A767: ExecModule (module.c:274)
==26512==    by 0x4A9711: PreProcessor (pre.c:884)
==26512==    by 0x4062F1: main (startup.c:1519)
==26512== 

Freeze in FactArg

In the following code, FactArg seems never to return. (At least extremely slow.)

CF den;
S ep,w;
L F =
   + den(226492416*ep^4*w - 679477248*ep^4*w^2 + 452984832*ep^4*
  w^3 + 452984832*ep^4*w^4 - 679477248*ep^4*w^5 + 226492416*ep^4*
  w^6 - 1887436800*ep^5*w + 5775556608*ep^5*w^2 - 4001366016*ep^5
  *w^3 - 3774873600*ep^5*w^4 + 5888802816*ep^5*w^5 - 2000683008*
  ep^5*w^6 - 1730150400*ep^6*w + 4756340736*ep^6*w^2 - 2592079872
  *ep^6*w^3 - 3460300800*ep^6*w^4 + 4322230272*ep^6*w^5 -
  1296039936*ep^6*w^6 + 51111788544*ep^7*w - 156153937920*ep^7*
  w^2 + 107860721664*ep^7*w^3 + 102223577088*ep^7*w^4 -
  158972510208*ep^7*w^5 + 53930360832*ep^7*w^6 - 88394956800*ep^8
  *w + 278057189376*ep^8*w^2 - 202534551552*ep^8*w^3 -
  176789913600*ep^8*w^4 + 290929508352*ep^8*w^5 - 101267275776*
  ep^8*w^6 - 350459265024*ep^9*w + 1065105752064*ep^9*w^2 -
  728374444032*ep^9*w^3 - 700918530048*ep^9*w^4 + 1078833709056*
  ep^9*w^5 - 364187222016*ep^9*w^6 + 1143994318848*ep^10*w -
  3545436782592*ep^10*w^2 + 2514896289792*ep^10*w^3 +
  2287988637696*ep^10*w^4 - 3658890608640*ep^10*w^5 +
  1257448144896*ep^10*w^6 + 54207184896*ep^11*w - 101166612480*
  ep^11*w^2 - 14495514624*ep^11*w^3 + 108414369792*ep^11*w^4 -
  39711670272*ep^11*w^5 - 7247757312*ep^11*w^6 - 3522057732096*
  ep^12*w + 10869824028672*ep^12*w^2 - 7651417128960*ep^12*w^3 -
  7044115464192*ep^12*w^4 + 11173474861056*ep^12*w^5 -
  3825708564480*ep^12*w^6 + 3387722563584*ep^13*w -
  10557767811072*ep^13*w^2 + 7564645367808*ep^13*w^3 +
  6775445127168*ep^13*w^4 - 10952367931392*ep^13*w^5 +
  3782322683904*ep^13*w^6 + 1380798431232*ep^14*w - 4224234553344
  *ep^14*w^2 + 2925275381760*ep^14*w^3 + 2761596862464*ep^14*w^4
   - 4306073812992*ep^14*w^5 + 1462637690880*ep^14*w^6 -
  3140694835200*ep^15*w + 9744207052800*ep^15*w^2 - 6925634764800
  *ep^15*w^3 - 6281389670400*ep^15*w^4 + 10066329600000*ep^15*w^5
   - 3462817382400*ep^15*w^6 + 1087163596800*ep^16*w -
  3382286745600*ep^16*w^2 + 2415919104000*ep^16*w^3 +
  2174327193600*ep^16*w^4 - 3503082700800*ep^16*w^5 +
  1207959552000*ep^16*w^6)
;
factarg den;
.end

Freeze when PolyRatFun contains dot products

The latest version of FORM freezes for

V a;
CF rat;
PolyRatFun rat;
L F = rat(a.a,1);
P +s;
.end

while older versions printed an error message:

ERROR: polynomials and polyratfuns must contain symbols only

[parform] Crash in #FactDollar

This is an example that ParFORM freezes/aborts in #FactDollar. It seems that the problem occurs in workers.

S x,y;
S dummy1,dummy2;
*L F = 1+x+y;  * OK
L F = 1-x+y;   * BAD
*L F = 1+x-y;  * BAD
*L F = 1-x-y;  * OK
*L F = -1+x+y; * OK
*L F = -1-x+y; * BAD
*L F = -1+x-y; * BAD
*L F = -1-x-y; * OK
id dummy1 = dummy2;  * <-- any executable statements
.sort
#$F = F;
*.sort;  * <-- (1) workaround
#factdollar $F

#if `$F[0]' == 1
  #message $F[0] = `$F[0]'
  #message $F = `$F'
#else
  #do i=0,`$F[0]'
    #message $F[`i'] = `$F[`i']'
  #enddo
#endif
.end
==7665== Invalid read of size 4
==7665==    at 0x4924F7: Generator (proces.c:3013)
==7665==    by 0x42CD68: DollarFactorize (dollar.c:3178)
==7665==    by 0x4866C5: DoFactDollar (pre.c:6239)
==7665==    by 0x48C329: PreProcessor (pre.c:857)
==7665==    by 0x4BC3FE: main (startup.c:1519)
==7665==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Inserting .sort at line (1) somehow works as a workaround. ParFORM 4.1 (Aug 18 2015) didn't have this problem.

Optimization crashes with trivial expressions.

After commit 59aca15, the optimization fails with very trivial expressions like:

Local expr=1;
.sort
Format O2;
#Optimize expr;
.end

Error message:

test.frm Line 5 ==> Illegal empty value for preprocessor variable optimscheme_

The current git master and the "4.1" FORM binaries (build date Jan 13 2014) supplied on the FORM website are affected, but not the 4.1 release on github.

As we are using FORM in an automated environment, it would make additional effort to catch trivial expressions.

Wrong circular pattern match

Below is a FORM file with a bug description.

CF PG,PQx, VQQG;
*
*   PG is a gluon propagator
*   PQx is a cut quark propagator
*   VQQG is a quark-quark-gluon veretex
*
T  S(symmetric);

I  s0,...,s99;
I  v1,...,v99;
V  k0,...,k99;
V  p0,...,p9999;

CF Sigma;

*
*  Expression for the gluon self-energy (with one quark loop)
*
L RESULT = PG(S(v17,v18),k3 + k4) * PG(S(v37,v38),k3 + k4) * VQQG(s2,k4,s4,k3,v17, - k3 - k4) * VQQG(s24,k3,s22,k4,v37, - k3 - k4) * PQx(s2,s22,k4) *PQx(s4,s24,k3);

id PG(S(v19?,v2?),p12?)*VQQG(s5?,p5?,s7?,p7?,v2?,p2?)*PQx(s5?,s6?,p56?)*PQx(s7?,s8?,p78?)*VQQG(s8?,p8?,s6?,p6?,v3?,p86?)*PG(S(v3?,v4?),p34?) = Sigma(p34);
*
*        ^
*        |
*       BUG
*
*  The transformation rule above collects a gluon propagator
*  into a simple expression `Sigma(k3+k4)'. The current version
*  works as expected.
*
*  If you, however, change index `v19?' to `v1?' the rule above
*  works not as expected.
*
*  > form -v
*  FORM 4.1 (Jan 13 2014) 64-bits
*
*  > uname -a
*  Linux golf.gituliar.org 3.14.4-1-ARCH #1 SMP PREEMPT Tue May 13 16:41:39 CEST 2014 x86_64 GNU/Linux
*
.sort

Print +sss;
.end

Incompatible Mathematica output

When printing expressions in Mathematica format sometimes output contains newlines (see example below) which are treated by Mathematica as end of the expression. Because of that Mathematica ignores everything after the first newline.

My solution is to wrap a whole output expression in parentheses, e.g. F = ( <expr> ), but you of course may have other ideas.

CF f,g;
S x;

L F = (x+1)^2*(f(x)+g(x))^5;

Format Mathematica;

Bracket x;
Print +s;
.end

$-variables can't obtain the contents of the wildcard by match(x?$x)

The following program gave me an unexpected result:

S x,a;
L F = a;
if (match(x?$x));
  P "%t: matched (%$)", $x;
endif;
.sort
#message x=`$x'
.end

The output was

 + a: matched (***)
~~~x=

If I put many option to the match function,

if (match(many,x?$x));

then it works well:

 + a: matched (a)
~~~x=a

Problems when calling external programs

This is probably an OS-related issue rather than a FORM bug, and maybe we cannot make any improvements, but still I would like to put a note about it. I am using a Desktop PC with Scientific Linux 6.6, x86_64, 7804MB Mem + 7967MB Swap. The problem I hit is, as a simple example,

#:MaxTermSize 2M
#:WorkSpace 2G
#system echo OK
.end

fails at use of #system:

foo.frm Line 4 ==> System call returned with error condition

If I remove the settings of MaxTermSize and WorkSpace, the program works well. A similar situation was already described in this post in the forum. But now the origin of the problem looks like: if a program allocates big memory blocks, then the system call for system() fails.

Note that the above program consumes only a small memory space (as you can see, for example, by top). GNU time utility reports the maximum resident set size is 1720KB. But actually the program allocates a very large memory space. valgrind reports 14GB memory blocks are still reachable (bigger than Mem+Swap).

#ifdef `VAR' and #if ( isdefined(VAR) ) are not exactly the same

Connected to the fix in the manual (f11fa12), the manual now says

Technically #ifdef `VAR' and #if ( isdefined(VAR) ) are the same.

To be exact, this statement is not true when VAR is defined but empty.

#define VAR ""

#ifdef `VAR'
  #message VAR is defined (1)
#endif
#if (isdefined(VAR))
  #message VAR is defined (2)
#endif

.end

prints only

~~~VAR is defined (2)

Behaviour of both #ifdef and isdefined are more or less reasonable to me. (At least changing the behaviour of #ifdef will cause disasters in many of my codes.) Maybe the manual should be changed a bit?

Installation issues

Hi,

I have cloned the git repo and am compiling with gcc (Ubuntu 4.8.2-19ubuntu1). During compilation, I get one warning

In file included from tools.c:54:0:
tools.c: In function โ€˜TruncateFileโ€™:
form3.h:422:31: warning: ignoring return value of โ€˜ftruncateโ€™, declared with attribute warn_unused_result [-Wunused-result]
 #define Utruncate(f) ftruncate(f->descriptor,0);
                               ^
tools.c:1401:3: note: in expansion of macro โ€˜Utruncateโ€™
   Utruncate(f);
   ^

Probably unrelated, when I try to make check, I get

/bin/bash:1: Invalid char `\x7F' in expression
/bin/bash:1: Invalid char `\x02' in expression
/bin/bash:1: Invalid char `\x01' in expression
/bin/bash:1: Invalid char `\x01' in expression
/bin/bash:1:in `<main>': uninitialized constant ELF (NameError)
make[3]: *** [form.rb.log] Error 1
make[3]: Leaving directory `/home/bijancn/form/check'
make[2]: *** [check-TESTS] Error 2

Trying to make manual.pdf, I stumpled upon a problem with manualdate.tex. With my locale I get 22 Mai 2014 with date +"%d %b %Y" which is not accepted by date -d ('invalid date'). A quick fix that allowed me to build the manual was to use date -I (ISO format) instead of date +"%d %b %Y" in the Makefile.am. Maybe you want to use this.

When I try a trivial example, it seems to run fine, except I get

    Format 03;
 ... Too small value for linesize corrected to 39
    #optimize expr
    Print;
    .end

This might be connected to the failed make check? I could only trace this problem to FG.cTable but I don't know how to fix it. I have plenty of space for windows so a linesize of 39 looks quite annoying.

Factorize/FactDollar are much slower than FactArg

I am trying to switch from FactArg to FactDollar to avoid the curse of MaxTermSize. The major problem is that FactDollar is really much slower than FactArg.

I put a test program at https://gist.githubusercontent.com/tueda/5f83e562854158b5a62f/raw/test1.frm. The file contains two expressions F1 and F2. The timing I obtained for F1 was

~~~factarg : .01 sec
~~~#factdollar : 7.74 sec
~~~factdollar : 7.81 sec
~~~factorize : 7.75 sec

and the timing for F2 was

~~~factarg : .01 sec
~~~#factdollar : 350.05 sec
~~~factdollar : 350.31 sec
~~~factorize : 356.11 sec

Maybe the recent improvements do not apply for them?

[cygwin] "make check" fails

Here I just record what I encountered for make check within Cygwin 1.7.30 (both x86_64 and i686) on Windows 7 (SP1, x86_64):

make  check-TESTS
make[1]: Entering directory '/home/tueda/tmp/form-4.1/check'
Run options:

# Running tests:

EEEEEEE./form.rb:87: [BUG] Segmentation fault
ruby 1.9.3p545 (2014-02-24) [x86_64-cygwin]

-- Control frame information -----------------------------------------------
c:0026 p:---- s:0108 b:0108 l:000107 d:000107 CFUNC  :close
c:0025 p:0233 s:0105 b:0105 l:000ae0 d:000ae0 METHOD ./form.rb:87
c:0024 p:0018 s:0093 b:0093 l:000092 d:000092 METHOD /home/tueda/tmp/form-4.1/check/examples.rb:1070
c:0023 p:0073 s:0090 b:0090 l:000089 d:000089 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:949
c:0022 p:0025 s:0084 b:0084 l:000083 d:000083 METHOD /usr/lib/ruby/1.9.1/test/unit/testcase.rb:17
c:0021 p:0090 s:0080 b:0080 l:000068 d:000079 BLOCK  /usr/lib/ruby/1.9.1/minitest/unit.rb:787
c:0020 p:---- s:0074 b:0074 l:000073 d:000073 FINISH
c:0019 p:---- s:0072 b:0072 l:000071 d:000071 CFUNC  :map
c:0018 p:0124 s:0069 b:0069 l:000068 d:000068 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:780
c:0017 p:0020 s:0061 b:0060 l:000050 d:000059 BLOCK  /usr/lib/ruby/1.9.1/test/unit.rb:565
c:0016 p:---- s:0056 b:0056 l:000055 d:000055 FINISH
c:0015 p:---- s:0054 b:0054 l:000053 d:000053 CFUNC  :each
c:0014 p:0053 s:0051 b:0051 l:000050 d:000050 METHOD /usr/lib/ruby/1.9.1/test/unit.rb:563
c:0013 p:0189 s:0045 b:0045 l:000044 d:000044 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:746
c:0012 p:0013 s:0035 b:0035 l:000034 d:000034 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:909
c:0011 p:0012 s:0032 b:0032 l:000023 d:000031 BLOCK  /usr/lib/ruby/1.9.1/minitest/unit.rb:896
c:0010 p:---- s:0029 b:0029 l:000028 d:000028 FINISH
c:0009 p:---- s:0027 b:0027 l:000026 d:000026 CFUNC  :each
c:0008 p:0068 s:0024 b:0024 l:000023 d:000023 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:895
c:0007 p:0029 s:0020 b:0020 l:000019 d:000019 METHOD /usr/lib/ruby/1.9.1/minitest/unit.rb:884
c:0006 p:0022 s:0016 b:0016 l:000015 d:000015 METHOD /usr/lib/ruby/1.9.1/test/unit.rb:21
c:0005 p:0033 s:0012 b:0011 l:0012e8 d:000010 BLOCK  /usr/lib/ruby/1.9.1/test/unit.rb:326
c:0004 p:0036 s:0009 b:0009 l:000008 d:000008 METHOD /usr/lib/ruby/1.9.1/test/unit.rb:27
c:0003 p:0026 s:0006 b:0006 l:0012e8 d:000005 BLOCK  /usr/lib/ruby/1.9.1/test/unit.rb:325
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0005c8 d:0005c8 TOP

-- Ruby level backtrace information ----------------------------------------
/usr/lib/ruby/1.9.1/test/unit.rb:325:in `block in autorun'
/usr/lib/ruby/1.9.1/test/unit.rb:27:in `run_once'
/usr/lib/ruby/1.9.1/test/unit.rb:326:in `block (2 levels) in autorun'
/usr/lib/ruby/1.9.1/test/unit.rb:21:in `run'
/usr/lib/ruby/1.9.1/minitest/unit.rb:884:in `run'
/usr/lib/ruby/1.9.1/minitest/unit.rb:895:in `_run'
/usr/lib/ruby/1.9.1/minitest/unit.rb:895:in `each'
/usr/lib/ruby/1.9.1/minitest/unit.rb:896:in `block in _run'
/usr/lib/ruby/1.9.1/minitest/unit.rb:909:in `run_tests'
/usr/lib/ruby/1.9.1/minitest/unit.rb:746:in `_run_anything'
/usr/lib/ruby/1.9.1/test/unit.rb:563:in `_run_suites'
/usr/lib/ruby/1.9.1/test/unit.rb:563:in `each'
/usr/lib/ruby/1.9.1/test/unit.rb:565:in `block in _run_suites'
/usr/lib/ruby/1.9.1/minitest/unit.rb:780:in `_run_suite'
/usr/lib/ruby/1.9.1/minitest/unit.rb:780:in `map'
/usr/lib/ruby/1.9.1/minitest/unit.rb:787:in `block in _run_suite'
/usr/lib/ruby/1.9.1/test/unit/testcase.rb:17:in `run'
/usr/lib/ruby/1.9.1/minitest/unit.rb:949:in `run'
/home/tueda/tmp/form-4.1/check/examples.rb:1070:in `test1'
./form.rb:87:in `execute'
./form.rb:87:in `close'

-- Other runtime information -----------------------------------------------

* Loaded script: ./form.rb

* Loaded features:

    0 enumerator.so
    1 /usr/lib/ruby/1.9.1/x86_64-cygwin/enc/encdb.so
    2 /usr/lib/ruby/1.9.1/x86_64-cygwin/enc/shift_jis.so
    3 /usr/lib/ruby/1.9.1/x86_64-cygwin/enc/trans/transdb.so
    4 /usr/lib/ruby/1.9.1/rubygems/defaults.rb
    5 /usr/lib/ruby/1.9.1/x86_64-cygwin/rbconfig.rb
    6 /usr/lib/ruby/1.9.1/rubygems/deprecate.rb
    7 /usr/lib/ruby/1.9.1/rubygems/exceptions.rb
    8 /usr/lib/ruby/1.9.1/rubygems/custom_require.rb
    9 /usr/lib/ruby/1.9.1/rubygems.rb
   10 /usr/lib/ruby/1.9.1/open3.rb
   11 /usr/lib/ruby/1.9.1/optparse.rb
   12 /usr/lib/ruby/1.9.1/minitest/unit.rb
   13 /usr/lib/ruby/1.9.1/prettyprint.rb
   14 /usr/lib/ruby/1.9.1/pp.rb
   15 /usr/lib/ruby/1.9.1/test/unit/assertions.rb
   16 /usr/lib/ruby/1.9.1/test/unit/testcase.rb
   17 /usr/lib/ruby/1.9.1/test/unit.rb
   18 /home/tueda/tmp/form-4.1/check/examples.rb
   19 /home/tueda/tmp/form-4.1/check/parser.rb
   20 /home/tueda/tmp/form-4.1/check/symmetrize.rb
   21 /home/tueda/tmp/form-4.1/check/table.rb

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

/bin/sh: line 5:  6516 Aborted                 (core dumped) /usr/bin/ruby -I . ${dir}$tst
FAIL: form.rb
===============================
1 of 1 test failed
Please report to [email protected]
===============================
Makefile:294: recipe for target 'check-TESTS' failed

There are two problems:

  • The behaviour of strace differs from that on Linux. It just ignores the -ff option. Moreover, the system call exit_group is not called on Cygwin, so the return_value method always fails.
  • The test program Sec_15 takes about 10 seconds under the strace run. (The output looks OK.) So the form.rb often tries to kill the process due to TIMEOUT=10, and somehow causes a segfault of Ruby at closing @outputstream (maybe still used by the process being killed?).

Calling procedures with delayed substitutions

I was just trying some tricky things and found the following code makes FORM freeze:

#define CALL(a) "
#call Test(`~a')
"

#procedure Test(a)
  #message a=`a'
#endprocedure

`CALL(1)'

.end

It seems to be an interference of the variables with the same name "a" between calling the procedure and the delayed substitution.

A workaround can be (1) to use different names:

#define CALL(a1) "
#call Test(`~a1')
"

#procedure Test(a)
  #message a=`a'
#endprocedure

`CALL(1)'

.end

or (2) not to give the arguments for the procedure (although it is a bit mysterious why it works):

#define CALL(a) "
#call Test
"

#procedure Test
  #message a=`a'
#endprocedure

`CALL(1)'

.end

Exit may fail to exit with TFORM

Sometimes the Exit statement causes strange things with TFORM. The following program should quit immediately,

S a,x1,...,x9;
L F = a*(x1+...+x9);
*L F = a+(x1+...+x9);
.sort
if (count(a,1)) exit;
.end

but for i in {1..100}; do tform -w4 test.frm; done (in bash) easily gets stuck. I also got "double free or corruption (fasttop)" errors from glibc.

Because L F = a+(x1+...+x9), i.e., only one term with "a", doesn't lead this problem, I guess it comes from that two or more threads try to exit.

form -y error with dollar variable

The simple program:

#$C=0;
#write "TEST %$",$C;
.end

crashes in form -y with the error:

 write instruction: $C has not been defined

Normal form runs fine.

Linefeeds in the format string in #write

Problem
I'm not sure whether or not intentionally #(re)define and #write were designed to accept strings containing linefeeds (because the manual doesn't mention such cases), but I think this undocumented feature could be useful. There is a problem about linefeeds in the format string of #write. They don't reset the internal counter for characters in the line, i.e.,

Format fortran;
#define decl "
      double precision a1,a2,a3,a4,a5,a6,a7,a8,a9
      double precision b1,b2,b3,b4,b5,b6,b7,b8,b9
"
#write "`decl'"

prints


      double precision a1,a2,a3,a4,a5,a6,a7,a8,a9
      double precisio
     & n b1,b2,b3,b4,b5,b6,b7,b8,b9

This is a valid Fortran code but the line break in the second line is not intended.
Similar things can occur in use of #show and Print "...".

Suggestion
For #write, change writeToChannel such that LINEFEED is treated as \n. It can be archived by inserting 2 lines around pre.c:5722:

diff --git a/sources/pre.c b/sources/pre.c
index 0d8f1fa..932ca5c 100644
--- a/sources/pre.c
+++ b/sources/pre.c
@@ -5719,9 +5719,11 @@ int writeToChannel(int wtype, UBYTE *s, HANDLERS *h)
                                to[-2] = '&';
                        }
                }
+               if ( *fstring == LINEFEED ) goto linefeed;
                if ( *fstring == '\\' ) {
                        fstring++;
                        if ( *fstring == 'n' ) {
+linefeed:
                                num = to - Out;
                                WriteString(wtype,Out,num);
                                to = Out;

For #show and Print "...", MesPrint needs modifications for the format string and for inserted strings by %s around message.c:223 and 343:

diff --git a/sources/message.c b/sources/message.c
index 4ce11ba..7913606 100644
--- a/sources/message.c
+++ b/sources/message.c
@@ -220,8 +220,13 @@ va_dcl
                }
 */
                else if ( *s != '%' ) {
+                       if ( *s == LINEFEED ) {
+                               s++;
+                               goto linefeed;
+                       }
                        *t++ = *s++;
                        if ( t >= stopper ) {
+linefeed:
                                num = t - Out;
                                WriteString(ERROROUT,(UBYTE *)Out,num);
                                num = 0; t = Out;
@@ -335,6 +340,13 @@ va_dcl
                        else if ( *s == 's' ) {
                                u = va_arg(ap,char *);
                                while ( *u ) {
+                                       if ( *u == LINEFEED ) {
+                                               u++;
+                                               num = t - Out;
+                                               WriteString(ERROROUT,(UBYTE *)Out,num);
+                                               t = Out;
+                                               continue;
+                                       }
                                        if ( t >= stopper ) {
                                                num = t - Out;
                                                WriteString(ERROROUT,(UBYTE *)Out,num);

I think hopefully these changes don't break any existing programs and don't cause any major performance problems.

Related problem
By the way, the manual says \n can be used for a linefeed for Print statement, but it doesn't work.

L F = 1;
P "a\nb";
.end

just prints

anb

For this, it seems that compcomm.c:1528 needs modifications. (Just removing the if line is OK or has some side effects?)

Broken terms with Collect, TFORM -w >= 3

If I run the following program, which is basically a test example heavily using the Collect statement, with -w3 or more threads in TFORM, something wrong often happens, like "Unexpected code in ReNumber" or just freezing, probably depending on some race condition:

On fewerstats;

* The problem size.
#ifndef `N'
#define N "8"
#endif

#message N=`N'

S x1,...,x19;
CF f1,f2;

L F = (x1+...+x19)^`N';
.sort

* Repeat Bracket-Collect.

#do i=1,9
  B x`i',x1`i';
  .sort:B`i';
  Collect, f1, f2;
  .sort:Collect`i';
  id f1(x1?) = x1;
  id f2(x2?) = x2;
#enddo

* Check the result.

.sort
#do i=1,19
  id x`i' = 1;
#enddo
.sort
Drop F;
L ZERO = F - 19^`N';
.sort
#if `ZERO_' == 0
  #message FAILED
  #terminate 1
#endif
.sort
#message OK
.end

I also ran the program with -w0, -w1, -w2 more than 100 times for each case, but I haven't experienced any problems. I guess there might be a thread unsafe code around SortBot(?)

This issue was found originally in a discussion with Matthias Steinhauser.

Missing features in the manual

Description of the following features/behaviour are still missing in the reference manual.

  • DropSymbols.
  • Some options of Normalize statement (at least I know ^-1).
  • The behaviour that FORM does nothing for mod_(2,1) (the second argument is one). Those who are familiar with "mod" functions in other programming languages may expect it would be replaced with 0. Should we mention it in the manual?

New test suites

I was thinking about test suites in check directory. As in #15, it doesn't work in Cygwin or other UNIX systems because it uses strace. Moreover, in Jens's test suites, one should write a test program in Ruby language and it could be a hurdle why no one writes tests for make check. So, I made a prototype of new test suites, which is designed as

  • not to use strace,
  • test programs are actually FORM programs with some additional codes.

The implementation is still done in Ruby, though a similar program can be written in Perl etc.

I made a (temporary) repository for it. You can clone it by

git clone https://github.com/tueda/test-form-check2.git

which should make a directory test-form-check2. After entering check2 subdirectory in it, you can execute check.rb.

cd test-form-check2
cd check2
./check.rb

By default form in $PATH is used. You may try it with tform (with -w4 by default)

./check.rb tform

or you can explicitly specify the path to the form/tform/parform binary.

./check.rb /path/to/form

As I wrote in #17, #18, #19, some tests are known to fail. form fails for examples.frm#Dictionaries_1. In addition to it, tform fails for examples.frm#PolyandFact_11. parform fails for examples.frm#Sta_Fill_2 and examples.frm#Sta_Fill_4.

In this test suite, tests are provided in *.frm files, and one test is given as a fold. A typical example is

*--#[ TestID :
* FORM program here.
S x;
L F = (1+x)^2;
P;
.end
# Ruby program after ".end" to check the result.
assert succeeded?
assert result("F") =~ terms("1+2*x+x^2")
*--#] TestID :

The block before .end is regarded as a FORM program, while the block after .end is regarded as a code block in Ruby to check the output. In this example, succeeded? checks if the FORM program ran successfully without any errors, and result("F") =~ terms("1+2*x+x^2") checks if the whole output for F by Print statement matches with a string 1+2*x+x^2 (whitespaces including new lines are ignored).

Each fold is actually translated to a Ruby unit test class, so TestID should be a valid identifier name and must be unique (maybe this rule can be relaxed).

If any Ruby code is not given after .end, it's equivalent to assert succeeded? by default. So just writing a FORM test program can be itself a test program for this test suite.

Putting the following code in each *.frm file,

#ifndef `TEST'
  #message Use -D TEST=XXX
  #terminate
#else
  #include `NAME_' # `TEST'
#endif
.end

one can run a test as a pure FORM program like

form -D TEST=TestID test.frm

Actually, examples.frm and fixes.frm in the test suite have this code in the header. For example,

form -D TEST=Dictionaries_1 examples.frm

runs the FORM program part of the corresponding test, for which form currently fails.

Valgrind warnings when "on names"

When I tried to see what expressions are defined in a FORM program by on names, I got a segfault. The situation can be simplified as follows:

On allnames;
I mu;
.end

gives, with valgrind,

...
 Symbols
   i_#i pi_ coeff_ num_ den_ xarg_ dimension_ factor_ sep_
 Indices
==22722== Use of uninitialised value of size 8
==22722==    at 0x55552D: StrCopy (sch.c:69)
==22722==    by 0x5573D7: WriteLists (sch.c:877)
==22722==    by 0x4537DE: DoExecute (execute.c:760)
==22722==    by 0x478BB2: ExecModule (module.c:274)
==22722==    by 0x50FB3A: PreProcessor (pre.c:884)
==22722==    by 0x572A7C: main (startup.c:1519)
==22722== 
==22722== Invalid read of size 8
==22722==    at 0x444377: FindIndex (dict.c:313)
==22722==    by 0x5573C5: WriteLists (sch.c:877)
==22722==    by 0x4537DE: DoExecute (execute.c:760)
==22722==    by 0x478BB2: ExecModule (module.c:274)
==22722==    by 0x50FB3A: PreProcessor (pre.c:884)
==22722==    by 0x572A7C: main (startup.c:1519)
==22722==  Address 0x561cb80 is 16 bytes after a block of size 768 alloc'd
==22722==    at 0x4A06A2E: malloc (vg_replace_malloc.c:270)
==22722==    by 0x59A053: Malloc1 (tools.c:2205)
==22722==    by 0x59A68C: FromVarList (tools.c:2684)
==22722==    by 0x480EC9: AddDollar (names.c:2302)
==22722==    by 0x5710D0: StartVariables (startup.c:880)
==22722==    by 0x572962: main (startup.c:1463)
==22722== 
   iarg_ mu
 Vectors
   parg_
...

The "Use of uninitialised value" warning is from iarg_ (so on allnames) and could be harmless, it just copies uninitialied values that won't be used later. I feel "Invalid read" more dangerous.

Broken output of indices in functions

Currently make check fails due to a bug introduced in merging the dictionary branch. A test program is

I mu;
CF f;
L F = f(mu);
P;
.end

which somehow prints

   F =
      f(i_);

Broken functionalities of dictionaries?

Some functionalities of dictionaries in the manual seems not to work. (Or it's still incomplete?)

Adding a function into a dictionary,

CF f;
#opendictionary test
  #add f: "\ln"
#closedictionary
.end

gives a segfault.

Indices are not correctly translated.

T t;
Indices mu,nu,ro,si;
#opendictionary test
  #add mu: "\mu"
  #add nu: "\nu"
  #add ro: "\rho"
* #add si: "\sigma"
#closedictionary
L F = t(mu,nu,ro,si);
L G = t(mu,nu,ro);
#usedictionary test
P;
.end

gives

   F =
      t(mu,nu,ro,\rho);

   G =
      t(mu,nu,ro);

[tform] Segfault in factorizing a constant

TFORM terminates abnormally with the following program regardless of the number of threads:

S x,y;
L F = 1/2;
* It fails also for an factorized expression in the manual.
* LF F = -0*3*(x+1)*(x+2)/2*0*((x+3)*(x+4));
P;
.sort
Factorize F;
P;
.end

From using Valgrind, it seems that POLY_GETIDENTIFY(a.factor[0]) in poly_fix_minus_signs is invalid in this case.

Polyratfun infinite loop in Print statement

The following simple example generates an infinite loop in the Print statement:

S ep;
CF rat;
PolyRatFun rat(expand,ep,6);
L F  = rat(ep,ep);
Print;
.end

and when multiplied, it freezes:

S ep;
CF rat;
PolyRatFun rat(expand,ep,6);
L F  =rat(1,1)*rat(ep,ep);

.end

Set element {a+1} is interpreted as {a,-1}

Although it is natural that FORM can't handle set elements consisting of more then one term, like {a+1}, FORM actually accepts and misinterpret such elements. For example,

On names;
S a,x;
CF f;
L F = <f(a-1)>+...+<f(a+1)> + <f(-1)>+...+<f(1)>;
if (match(f(x?{a+1}))) discard;
P;
.end

gives

 Sets
   {}: a -1
   F =
      f( - 1 + a) + f(1 + a) + f(0) + f(1);

If the user gives {2*a}, FORM claims it's an illegal object for set elements. It would be worth to show the same error message and abort the program also for {a+1}.

IntoHide without any expression names doesn't work as the manual says

The reference manual says the IntoHide statement without any specifications of expression names makes all active expressions being put into the hidden storage at the end of the module, but somehow it is not implemented to do so in SetExpr(). Actually in the following example the expression F remains as an active local expression:

L F = 1;
.sort
IntoHide;
.sort
On names;
P;
.end

A trivial workaround is to specify all expression names, or to switch to Hide instead of IntoHide.

building with intel compilers

The settings for intel compilers are a bit outdated and cause warnings about deprecated options.

Here is a tiny patch for Makefile.am, which I used for successful builds recently:

diff --git a/sources/Makefile.am b/sources/Makefile.am
index 7c22084..1b61641 100644
--- a/sources/Makefile.am
+++ b/sources/Makefile.am
@@ -128,10 +128,10 @@ if ONAPPLE
 COMPILEFLAGS += -Wall -ipo -O3 -no-prec-div
 else
 if OPTPENTIUM
-COMPILEFLAGS += -Wall -ipo -O3 -no-prec-div -xP
+COMPILEFLAGS += -Wall -ipo -O3 -no-prec-div -xHost
 else
 if OPTOPTERON
-COMPILEFLAGS += -Wall -ipo -O3 -no-prec-div -xP
+COMPILEFLAGS += -Wall -ipo -O3 -no-prec-div -xHost
 else
 COMPILEFLAGS += -Wall -ipo -O3
 endif

Wrong normalization of PolyRatFun

The bug introduced in a795a9c is still there.

CF num,rat;
S n1,x;
L F = num(n1)*num(1/2);
id num(x?) = rat(x,1);
P "%t";
ModuleOption PolyRatFun=rat;
P +s;
.end

somehow gives

 + rat(n1,1)
   F =
       + rat(n1,1)
      ;

(I thought it was fixed in 4f6cb55, but not.)

SegFault when #optimizing trivial bracket

Hello,

The following form program causes a segmentation fault:

Symbol x;
Local expr = x;
Bracket x;
Print;
.sort

Format O3;
#optimize expr
Print;
.end

If the bracket is nontrivial,

Symbol x,y;
Local expr = x*(12+y);

the program runs fine.

This issue also occurred with Format O0, but that has been fixed with commit 8ee418f (I think)

Efficiently work out exponentiation with mixed commutative and non-commutative variables

The following code with mixed commutative and non-commutative variables generates too many intermediate terms:

CF a;
NF d, e;

L A = (a+d+e)^10;
.end


Time =       0.03 sec    Generated terms =      59049
               A         Terms in output =       2047
                         Bytes used      =      89916

The solution is simple: split the terms into a group of commutative terms and non-commutative terms, compute the binonium, and multiply the results. Alternatively, replace all the non-commutative terms by a placeholder.

CF a;
NF d, e;
L B = (a+d)^10;
id d = (d+e);

Print +s;

.end

Time =       0.04 sec    Generated terms =       2047
               B         Terms in output =       2047
                         Bytes used      =      89916

This should be done internally.

A silent crash in Id-statement

The following program crashes without any useful messages in the Id-statement (actually no match with F):

#-
* on Linux x86_64
#:maxtermsize 40000
#:workspace 40000000
#define N "700"
#define M "200"
CF Z,f,acc;
S n1,...,n`N';
S a1,...,a`N';
L F = Z(0) * f(<acc(n1,a1)>,...,<acc(n`N',a`N')>);
*L G = Z(0) * f(<acc(n1,a1)>,...,<acc(n`N',a`N')>,acc(1,1));
* Comsume the workspace.
#do i=1,`M'
  id Z(?a) = Z(?a);
#enddo
id f(?a,acc(a1?,1),?b) = f(acc(a1,1),?a,?b);
.end
FORM 4.1 (Apr 24 2015) 64-bits                   Run: Fri Jun  5 15:47:24 2015
    #-
Program terminating at foo.frm Line 16 --> 
  0.03 sec out of 0.03 sec

It looks like due to a shortage of the workspace, because setting M=100 makes the program work well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.