Subject: [PATCH] Add symmetrica
From: Nicolas Goaziou <[email-masked]>
To: [email-masked]
Cc: Andreas Enge <[email-masked]>
Date: Wed, 19 Jun 2019 12:08:10 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello,

The following patch adds Symmetrica 2.0. It builds, but I have a few
questions and remarks:

- I added the package in "sagemath.scm" because its main use would be
  with Sage, and it is already heavily patched by Sage. Should I move it
  to "algebra.scm" or "maths.scm"?

- The package creates a static library, because that is what Sage seems
  to expect (see <https://git.sagemath.org/sage.git/plain/build/pkgs/symmetrica/patches/makefile>).

- I'm not sure about the installation. Headers go into
  "%out/include/symmetrica" and static library into "%out/lib". Is that
  right?

Regards,

-- 
Nicolas Goaziou
From 1220d983e9b36636094daeeed332c44411b707bc Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <[email-masked]>
Date: Wed, 19 Jun 2019 07:57:57 +0200
Subject: [PATCH] gnu: Add symmetrica.

* gnu/packages/sagemath.scm (symmetrica): New variable.
* gnu/packages/patches/symmetrica-bruch.patch:
* gnu/packages/patches/symmetrica-int32.patch:
* gnu/packages/patches/symmetrica-return_values.patch:
* gnu/packages/patches/symmetrica-sort_sum_rename.patch: New files.
* gnu/local.mk (dist_patch_DATA): Add patches.
---
 gnu/local.mk                                  |   6 +-
 gnu/packages/patches/symmetrica-bruch.patch   |  38 ++
 gnu/packages/patches/symmetrica-int32.patch   |  37 ++
 .../patches/symmetrica-return_values.patch    |  14 +
 .../patches/symmetrica-sort_sum_rename.patch  | 340 ++++++++++++++++++
 gnu/packages/sagemath.scm                     |  62 ++++
 6 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/symmetrica-bruch.patch
 create mode 100644 gnu/packages/patches/symmetrica-int32.patch
 create mode 100644 gnu/packages/patches/symmetrica-return_values.patch
 create mode 100644 gnu/packages/patches/symmetrica-sort_sum_rename.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 74d2bafa8d..9d26b0b962 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1280,6 +1280,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/sssd-curl-compat.patch			\
   %D%/packages/patches/steghide-fixes.patch			\
   %D%/packages/patches/streamlink-update-test.patch		\
+  %D%/packages/patches/stumpwm-fix-broken-read-one-line.patch	\
   %D%/packages/patches/superlu-dist-awpm-grid.patch		\
   %D%/packages/patches/superlu-dist-fix-mpi-deprecations.patch	\
   %D%/packages/patches/superlu-dist-scotchmetis.patch		\
@@ -1288,7 +1289,10 @@ dist_patch_DATA =						\
   %D%/packages/patches/swig-guile-gc.patch			\
   %D%/packages/patches/swish-e-search.patch			\
   %D%/packages/patches/swish-e-format-security.patch		\
-  %D%/packages/patches/stumpwm-fix-broken-read-one-line.patch	\
+  %D%/packages/patches/symmetrica-bruch.patch			\
+  %D%/packages/patches/symmetrica-int32.patch			\
+  %D%/packages/patches/symmetrica-return_values.patch 		\
+  %D%/packages/patches/symmetrica-sort_sum_rename.patch 	\
   %D%/packages/patches/t1lib-CVE-2010-2642.patch		\
   %D%/packages/patches/t1lib-CVE-2011-0764.patch		\
   %D%/packages/patches/t1lib-CVE-2011-1552+.patch		\
diff --git a/gnu/packages/patches/symmetrica-bruch.patch b/gnu/packages/patches/symmetrica-bruch.patch
new file mode 100644
index 0000000000..ae88b79206
--- /dev/null
+++ b/gnu/packages/patches/symmetrica-bruch.patch
@@ -0,0 +1,38 @@
+--- src/bruch.c	2007-12-06 11:30:00.000000000 -0500
++++ b/bruch.c	2013-10-22 08:37:43.000000000 -0400
+@@ -975,14 +975,16 @@
+     ggterg = ggt_i(S_B_UI(bruch),S_B_OI(bruch));
+ 
+     if (ggterg == S_B_UI(bruch)) {
++        INT tmp = S_B_OI(bruch);
+         freeself_bruch(bruch);
+-        M_I_I(S_B_OI(bruch) / ggterg,bruch);
++        M_I_I(tmp / ggterg,bruch);
+         goto ende;
+         }
+ 
+     if (-ggterg == S_B_UI(bruch)) {
++        INT tmp = S_B_OI(bruch);
+         freeself_bruch(bruch);
+-        M_I_I(- S_B_OI(bruch) / ggterg,bruch);
++        M_I_I(- tmp / ggterg,bruch);
+         goto ende;
+         }
+ 
+@@ -1032,12 +1034,14 @@
+ 
+     if (S_O_K(S_B_U(bruch)) == INTEGER)
+         if (S_B_UI(bruch) == 1) { 
++            INT tmp = S_B_OI(bruch);
+             freeself_bruch(bruch);
+-            M_I_I(S_B_OI(bruch),bruch); 
++            M_I_I(tmp,bruch); 
+             goto ende; }
+         else if (S_B_UI(bruch) == -1) { 
++            INT tmp = S_B_OI(bruch);
+             freeself_bruch(bruch);
+-            M_I_I( - S_B_OI(bruch),bruch); 
++            M_I_I( - tmp,bruch); 
+             goto ende; }
+     if (NEGP(S_B_O(bruch)) && NEGP(S_B_U(bruch)))
+         {
diff --git a/gnu/packages/patches/symmetrica-int32.patch b/gnu/packages/patches/symmetrica-int32.patch
new file mode 100644
index 0000000000..b64f27d51e
--- /dev/null
+++ b/gnu/packages/patches/symmetrica-int32.patch
@@ -0,0 +1,37 @@
+diff -ru src/def.h c/def.h
+--- src/def.h	2007-12-06 17:30:56.000000000 +0100
++++ c/def.h	2013-10-19 18:42:55.118745730 +0200
+@@ -2,14 +2,9 @@
+ /* INT should always be 4 byte */
+ #ifndef DEF_H
+ 
+-
+-#ifdef __alpha
+-typedef  int INT;
+-typedef unsigned  int  UINT;
+-#else /* __alpha */
+-typedef long INT;
+-typedef unsigned long UINT;
+-#endif /* __alpha */
++#include <stdint.h>
++typedef int32_t INT;
++typedef uint32_t UINT;
+ 
+ #include <stdio.h>
+ #include <memory.h>
+@@ -65,10 +60,13 @@
+ 
+ 
+ /* definitionen fuer object.c */
+-typedef INT OBJECTKIND;   /* 4 byte */
++/* NOTE: partition code assumes that there is no unused space in the
++ * object struct when an INT is stored. This requires both OBJECTKIND
++ * and OBJECTSELF to have a size equal to a machine word. */
++typedef intptr_t OBJECTKIND;
+ 
+ typedef union {
+-	INT ob_INT;
++	intptr_t ob_INT;
+ 	INT * ob_INTpointer;
+ 	char *ob_charpointer;
+ 	struct bruch *ob_bruch;
diff --git a/gnu/packages/patches/symmetrica-return_values.patch b/gnu/packages/patches/symmetrica-return_values.patch
new file mode 100644
index 0000000000..e09c389337
--- /dev/null
+++ b/gnu/packages/patches/symmetrica-return_values.patch
@@ -0,0 +1,14 @@
+diff -ru src/part.c b/part.c
+--- src/part.c	Thu May 14 06:01:00 2009 -0400
++++ b/part.c 	Thu May 14 06:01:00 2009 -0400
+@@ -1767,8 +1767,8 @@
+ /* to compute number of partitions */
+ {
+     INT erg = OK;
+-    if (ni<0) return;
+-    if (not EMPTYP(S_V_I(vec,ni))) return;
++    if (ni<0) return 0;
++    if (not EMPTYP(S_V_I(vec,ni))) return 0;
+     else if (ni<=1) M_I_I(1,S_V_I(vec,ni));
+     else {
+     
diff --git a/gnu/packages/patches/symmetrica-sort_sum_rename.patch b/gnu/packages/patches/symmetrica-sort_sum_rename.patch
new file mode 100644
index 0000000000..2d9a2dae06
--- /dev/null
+++ b/gnu/packages/patches/symmetrica-sort_sum_rename.patch
@@ -0,0 +1,340 @@
+diff -r 5cd656a07aa5 src/bar.c
+--- a/bar.c	Thu May 14 06:01:00 2009 -0400
++++ b/bar.c	Thu May 14 07:38:17 2009 -0400
+@@ -237,7 +237,7 @@
+     g = callocobject();
+     e = S_V_I(a,0L);
+     f = S_V_I(a,1L);
+-    erg += sum(f,g);
++    erg += sym_sum(f,g);
+     j=0L;
+     for (i=0L;i<S_V_LI(e);i++)
+         j += S_V_II(e,i)*(i+1L);
+@@ -427,7 +427,7 @@
+     for (i=0L;i<S_V_LI(b);i++)
+         erg += kranztypus_to_matrix(S_V_I(c,i),S_V_I(b,i));
+     erg += freeall(c);
+-    erg += sort(b); /* AK 130592 */
++    erg += sym_sort(b); /* AK 130592 */
+     ENDR("makevectorof_class_bar");
+ }
+ 
+@@ -615,7 +615,7 @@
+     c = callocobject();
+     d = callocobject();
+     erg += lehmercode_bar(a,c);
+-    erg += sum(S_V_I(c,1L),b);
++    erg += sym_sum(S_V_I(c,1L),b);
+     for(i=0L;i<S_P_LI(a);i++)
+         {
+         if (S_V_II(S_V_I(c,0L),i) == 1L)
+diff -r 5cd656a07aa5 src/def.h
+--- a/def.h	Thu May 14 06:01:00 2009 -0400
++++ b/def.h	Thu May 14 07:38:17 2009 -0400
+@@ -3105,7 +3105,7 @@
+ extern INT so_character ();
+ extern INT so_dimension ();
+ extern OBJECTKIND s_o_k();
+-extern INT sort();
++extern INT sym_sort();
+ extern INT sort_rows_tableaux_apply();
+ extern INT sort_vector();
+ extern OBJECTSELF s_o_s();
+@@ -3271,7 +3271,7 @@
+ extern INT sub_part_part();
+ extern INT substitute_one_matrix ();
+ extern INT substitute_one_monopoly ();
+-extern INT sum();
++extern INT sym_sum();
+ extern INT sum_integervector();
+ extern INT sum_matrix();
+ extern INT sum_vector();
+diff -r 5cd656a07aa5 src/di.c
+--- a/di.c	Thu May 14 06:01:00 2009 -0400
++++ b/di.c	Thu May 14 07:38:17 2009 -0400
+@@ -1355,7 +1355,7 @@
+ 				m_il_nv(0L,weight_watcher);
+ 				m_il_nv(0L,perm_vec);
+ 				copy(S_V_I(FP,0L),fix);
+-				sort(fix);
++				sym_sort(fix);
+ 
+ 				get_perm(hweight,p,b,S_I_I(n),S_I_I(m),0L,
+ 						 perm_vec,weight_watcher,fix);
+@@ -1502,7 +1502,7 @@
+ 	if(ind == m)
+ 	{
+ 		mult_perm_fix(p,fix,hfix);
+-		sort(hfix);
++		sym_sort(hfix);
+ 		if(!hfix_in_ww(hfix,ww))
+ 		{
+ 			inc(ww);
+diff -r 5cd656a07aa5 src/ga.c
+--- a/ga.c	Thu May 14 06:01:00 2009 -0400
++++ b/ga.c	Thu May 14 07:38:17 2009 -0400
+@@ -632,7 +632,7 @@
+     else if (what == 0L)
+         erg += vertikal_sum(S_V_L(a),c);
+     erg += copy(a,d);
+-    erg += sort(d);
++    erg += sym_sort(d);
+     erg += m_il_p(S_V_II(d,S_V_LI(d)-1L),e); /* identitaet */
+     for (i=0L,k=0L,j=S_V_LI(d);i<S_P_LI(e);i++)
+         if (i+1L == S_V_II(d,k) )
+@@ -722,7 +722,7 @@
+ 
+     j=0L;
+     erg += append(h,g,h2); 
+-    erg += sort(h2);
++    erg += sym_sort(h2);
+     for (i=0L;i<S_V_LI(g);i++)
+         {
+         erg += m_i_i(S_V_II(g,i),S_P_I(a,j));
+diff -r 5cd656a07aa5 src/galois.c
+--- a/galois.c	Thu May 14 06:01:00 2009 -0400
++++ b/galois.c	Thu May 14 07:38:17 2009 -0400
+@@ -758,7 +758,7 @@
+ 		}
+         }
+     FREEALL2(v,nv);
+-    sort(res);
++    sym_sort(res);
+     }
+     S3R(k,phg_c,phg_d,"all_points_phg_store",res);
+     ENDR("all_points");
+diff -r 5cd656a07aa5 src/macro.h
+--- a/macro.h	Thu May 14 06:01:00 2009 -0400
++++ b/macro.h	Thu May 14 07:38:17 2009 -0400
+@@ -1,6 +1,8 @@
+ /* file: macro.h symmetrica source code */
+ #ifndef MACRO_H
+ 
++#include "string.h"
++
+ #ifdef SYMMAGMA
+ #define SYM_MALLOC(a) mem_malloc(a)
+ #else
+ #define C_O_K(a,b) ((a)->ob_kind = (OBJECTKIND)(b))
+--- a/nc.c	Thu May 14 06:01:00 2009 -0400
++++ b/nc.c	Thu May 14 07:38:17 2009 -0400
+@@ -204,7 +204,7 @@
+     erg += mult(S_NC_C(a),S_NC_C(b),d);
+     erg += m_gl_co(S_NC_GL(a),e);
+     erg += mult_apply(e,d);
+-    erg += sum(d,e);
++    erg += sym_sum(d,e);
+     erg += m_gl_go(S_NC_GL(a),d);
+     erg += div(e,d,c);
+     erg += freeall(e);
+@@ -617,7 +617,7 @@
+         erg += mult_nc_kranz(c,a,e);
+         erg += mult(S_V_I(e,1L),f,c);
+         erg += div(c,g,c);
+-        erg += sum(c,S_V_I(S_NC_C(b),S_I_I(d)));
++        erg += sym_sum(c,S_V_I(S_NC_C(b),S_I_I(d)));
+     }
+     erg += freeall(c); 
+     erg += freeall(d); 
+@@ -712,7 +712,7 @@
+     for(j = 0L; j<S_V_LI(c);j++) {
+         kranztypus_to_matrix(S_V_I(c,j),S_V_I(a,j)); 
+     }
+-    sort(a);
++    sym_sort(a);
+     freeall(f); freeall(h); freeall(c);
+     return OK;
+ }
+@@ -739,7 +739,7 @@
+         kranztypus_to_matrix(S_V_I(c,j),S_V_I(h,j)); 
+         }
+     
+-    sort(h); 
++    sym_sort(h); 
+     m_l_v(S_V_L(h),a);
+     for(j = 0L; j<S_V_LI(c);j++) {
+         typusorder(S_V_I(h,j), zb, za, S_V_I(a,j), f);
+@@ -789,7 +789,7 @@
+         erg += kranztypus_to_matrix(S_V_I(c,j),S_V_I(h,j)); 
+     }
+     
+-    erg += sort(h);
++    erg += sym_sort(h);
+     erg += typusorder(S_V_I(h,S_I_I(i)), zb, za, a, f);
+     erg += freeall(f); 
+     erg += freeall(c); 
+diff -r 5cd656a07aa5 src/nu.c
+--- a/nu.c	Thu May 14 06:01:00 2009 -0400
++++ b/nu.c	Thu May 14 07:38:17 2009 -0400
+@@ -531,13 +531,13 @@
+     ENDR("add");
+ }
+ 
+-INT sort(a) OP a;
++INT sym_sort(a) OP a;
+ /* sortiert das object in aufsteigender reihenfolge AK 270787 */
+ /* AK 160986 */ /* AK 280689 V1.0 */ /* AK 050390 V1.1 */
+ /* AK 070891 V1.3 */
+ {
+     INT erg = OK;
+-    EOP("sort(1)",a);
++    EOP("sym_sort(1)",a);
+ 
+     switch(S_O_K(a))
+     {
+@@ -547,9 +547,9 @@
+         erg += sort_vector(a);break;
+ #endif /* VECTORTRUE */
+     default:
+-        erg += WTO("sort",a); break;
++        erg += WTO("sym_sort",a); break;
+     };
+-    ENDR("sort");
++    ENDR("sym_sort");
+ }
+ 
+ INT length(a,d) OP a,d;
+@@ -641,7 +641,7 @@
+     ENDR("content");
+ }
+ 
+-INT sum(a,res) OP a,res;
++INT sym_sum(a,res) OP a,res;
+ /* AK 280689 V1.0 */ /* AK 050390 V1.1 */ /* AK 120391 V1.2 */
+ /* AK 140891 V1.3 */
+ /* AK 170298 V2.0 */
+@@ -649,7 +649,7 @@
+     INT erg = OK;
+     COP("sum(1)",a);
+     COP("sum(2)",res);
+-    CE2(a,res,sum);
++    CE2(a,res,sym_sum);
+ 
+     switch(S_O_K(a))
+     {
+@@ -680,7 +680,7 @@
+         erg += WTO("sum",a); break;
+     };
+ 
+-    ENDR("sum");
++    ENDR("sym_sum");
+ }
+ 
+ 
+diff -r 5cd656a07aa5 src/part.c
+--- a/part.c	Thu May 14 06:01:00 2009 -0400
++++ b/part.c	Thu May 14 07:38:17 2009 -0400
+@@ -347,7 +347,7 @@
+     if (a == b) { /* a := a+a */
+         if (S_PA_K(a) == VECTOR) {
+             erg += append_apply_vector(S_PA_S(a),S_PA_S(b));
+-            erg += sort(S_PA_S(a));
++            erg += sym_sort(S_PA_S(a));
+             goto endr_ende;
+         }
+         else if (S_PA_K(a) == EXPONENT) {
+@@ -406,7 +406,7 @@
+             k=S_PA_LI(b)-1;
+ /*
+             erg += append_apply_vector(S_PA_S(a),S_PA_S(b));
+-            erg += sort(S_PA_S(a));
++            erg += sym_sort(S_PA_S(a));
+ */
+             inc_vector_co(S_PA_S(a),S_PA_LI(b));
+             for (j=S_PA_LI(a)-1;j>=0;j--)
+diff -r 5cd656a07aa5 src/perm.c
+--- a/perm.c	Thu May 14 06:01:00 2009 -0400
++++ b/perm.c	Thu May 14 07:38:17 2009 -0400
+@@ -833,9 +833,9 @@
+     /* s = Anzahl der spalten */
+         
+     s = S_V_LI(S_V_I(a,0L));
+-    sum(S_V_I(a,0L),summe);/* composition ist vector */
++    sym_sum(S_V_I(a,0L),summe);/* composition ist vector */
+     z = S_I_I(summe);
+-    FREEALL(summe); 
++    FREEALL(summe);
+     m_ilih_nm(s,z,b); 
+     C_O_K(b,KRANZTYPUS);
+     for (i=0L;i<s;i++)
+@@ -1114,7 +1114,7 @@
+         erg += kranztypus_to_matrix(S_V_I(c,i),S_V_I(h,i)); 
+     }
+     
+-    erg += sort(h);
++    erg += sym_sort(h);
+ 
+     erg += chartafel(b,ct);
+ 
+@@ -1926,7 +1926,7 @@
+     OP c;
+     c = CALLOCOBJECT();
+     erg += lehmercode_permutation(a,c); /*result is a vector */
+-    erg += sum(c,b); 
++    erg += sym_sum(c,b); 
+     FREEALL(c);
+     }
+     ENDR("numberof_inversionen");
+@@ -2364,7 +2364,7 @@
+     COP("rz_lehmercode(2)",b);
+ 
+     zw = callocobject();
+-    erg += sum(lc,zw); 
++    erg += sym_sum(lc,zw); 
+     if (NULLP(zw)) 
+         {
+         erg += m_il_integervector((INT)0,b);
+diff -r 5cd656a07aa5 src/rest.c
+--- a/rest.c	Thu May 14 06:01:00 2009 -0400
++++ b/rest.c	Thu May 14 07:38:17 2009 -0400
+@@ -3998,7 +3998,7 @@
+                 oj = j;
+                 }
+         }
+-    erg += sum(c,b);
++    erg += sym_sum(c,b);
+ eee:
+     erg += freeall(c);
+     ENDR("charge_word");
+diff -r 5cd656a07aa5 src/ta.c
+--- a/ta.c	Thu May 14 06:01:00 2009 -0400
++++ b/ta.c	Thu May 14 07:38:17 2009 -0400
+@@ -1596,7 +1596,7 @@
+     {
+     OP d,e;
+     e = CALLOCOBJECT();
+-    erg += sum(content,e); /* AK 271098 */
++    erg += sym_sum(content,e); /* AK 271098 */
+     d = CALLOCOBJECT();
+     erg += weight(shape,d);
+     if (NEQ(d,e))
+@@ -1821,7 +1821,7 @@
+     CE3(matrix, column_index, row_index,matrix_twoword);
+     c = callocobject();
+     erg += zeilen_summe(matrix,c);
+-    erg += sum(c,c);
++    erg += sym_sum(c,c);
+     erg += m_l_v(c,column_index);
+     erg += m_l_v(c,row_index);
+     for(i=0,l=0;i<S_M_HI(matrix);i++)
+diff -r 5cd656a07aa5 src/zyk.c
+--- a/zyk.c	Thu May 14 06:01:00 2009 -0400
++++ b/zyk.c	Thu May 14 07:38:17 2009 -0400
+@@ -804,7 +804,7 @@
+     zykeltypvec = CALLOCOBJECT();
+     ak_order = CALLOCOBJECT();
+ 
+-    sum(numztvec,ak_order); /* AK 060295 */
++    sym_sum(numztvec,ak_order); /* AK 060295 */
+ 
+ 
+ 
+@@ -1176,7 +1176,7 @@
+     erg += m_i_i(0,c);
+     while (z!=NULL)
+         {
+-        erg += sum(S_PO_S(z),e);
++        erg += sym_sum(S_PO_S(z),e);
+         erg += hoch(b,e,e);
+         erg += mult_apply(S_PO_K(z),e);
+         erg += add_apply(e,c);
diff --git a/gnu/packages/sagemath.scm b/gnu/packages/sagemath.scm
index 732011bf36..6fb24f1f72 100644
--- a/gnu/packages/sagemath.scm
+++ b/gnu/packages/sagemath.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Andreas Enge <[email-masked]>
+;;; Copyright © 2019 Nicolas Goaziou <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -17,6 +18,7 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu packages sagemath)
+  #:use-module (gnu packages)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system python)
@@ -228,3 +230,63 @@ represented as strings.")
                 "1wfivlwp30mzdy1697w7rzb8caajim50mc8h27k82yipn2qc5n4i"))))
     (inputs
      `(("fflas-ffpack" ,fflas-ffpack-2.3.2)))))
+
+(define-public symmetrica
+  (package
+    (name "symmetrica")
+    (version "2.0")
+    (source (origin
+              (method url-fetch/tarbomb)
+              (uri (let ((v (string-join (string-split version #\.) "_")))
+                     (string-append "http://www.algorithm.uni-bayreuth.de/"
+                                    "en/research/SYMMETRICA/"
+                                    "SYM" v "_tar.gz")))
+              (sha256
+               (base32
+                "1qhfrbd5ybb0sinl9pad64rscr08qvlfzrzmi4p4hk61xn6phlmz"))
+              ;; Taken from <https://git.sagemath.org/sage.git/plain/build/pkgs/symmetrica/patches/>
+              (patches (search-patches "symmetrica-bruch.patch"
+                                       "symmetrica-int32.patch"
+                                       "symmetrica-return_values.patch"
+                                       "symmetrica-sort_sum_rename.patch"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f                      ;no test
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'fix-makefile
+           (lambda _
+             (substitute* "makefile"
+               (("cc -c") "gcc -c"))
+             #t))
+         (add-after 'fix-makefile 'turn-off-banner
+           (lambda _
+             (substitute* "de.c"
+               (("(INT no_banner = )FALSE" _ pre) (string-append pre "TRUE")))
+             #t))
+         (delete 'configure)            ;no configure script
+         (replace 'install              ;no install target
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib"))
+                    (inc (string-append out "/include/symmetrica"))
+                    (doc (string-append out "/share/doc/symmetrica-" ,version))
+                    (static "libsymmetrica.a"))
+               ;; Build static library.
+               (apply invoke "ar" "crs" static (find-files "." "\\.o$"))
+               (invoke "ranlib" static)
+               ;; Install static library and headers.
+               (for-each (lambda (f) (install-file f inc))
+                         (find-files "." "\\.h$"))
+               (install-file "libsymmetrica.a" lib)
+               ;; Install documentation.
+               (for-each (lambda (f) (install-file f doc))
+                         (find-files "." "\\.doc$"))
+               #t))))))
+    (home-page "http://www.algorithm.uni-bayreuth.de/en/research/SYMMETRICA/")
+    (synopsis "Combinatoric C Library")
+    (description "Symmetrica is a library for combinatorics.  It has support
+for the representation theory of the symmetric group and related groups,
+combinatorics of tableaux, symmetric functions and polynomials, Schubert
+polynomials, and the representation theory of Hecke algebras of type A_n.")
+    (license license:public-domain)))
-- 
2.22.0