1##
2InstallMethod( ViewString,
3               "for a Normaliz cone",
4               [ IsNormalizCone ],
5function( r )
6    # TODO: May print more information when present
7    return "<a Normaliz cone>";
8end );
9
10InstallGlobalFunction( NmzConeProperty,
11function( cone, prop )
12    local result, t, shift, poly, tmp, denom;
13    result := _NmzConeProperty(cone, prop);
14    if prop = "Grading" then
15        denom := NmzConeProperty(cone, "GradingDenom");;
16        return result / denom;
17    fi;
18    if prop = "HilbertSeries" then
19        t := Indeterminate(Integers, "t");
20        poly := UnivariatePolynomial(Integers, result[1], t);
21        shift := result[3];
22        if shift > 0 then
23            poly := poly * t^shift;
24        fi;
25        if shift < 0 then
26            poly := poly / t^(-shift);
27        fi;
28        tmp := Collected(result[2]);
29        return [poly, tmp];
30    fi;
31    if prop = "HilbertQuasiPolynomial" then
32        t := Indeterminate(Rationals, "t");
33        denom := Remove(result);
34        poly := List(result, coeffs -> UnivariatePolynomial(Rationals, coeffs, t));
35        return poly / denom;
36    fi;
37    return result;
38end );
39
40InstallGlobalFunction("NmzPrintConeProperties", function(cone)
41    local prop, val;
42    if not IsNormalizCone(cone) then
43        Error("First argument must be a Normaliz cone object");
44        return;
45    fi;
46    for prop in NmzKnownConeProperties(cone) do
47        val := NmzConeProperty(cone, prop);
48        Print(prop," = ");
49        if IsMatrix(val) then
50            Print("\n");
51        fi;
52        Display(val);
53    od;
54end);
55
56BindGlobal("_NmzPrintSomeConeProperties", function(cone, excluded)
57    local prop, val;
58    if not IsNormalizCone(cone) then
59        Error("First argument must be a Normaliz cone object");
60        return;
61    fi;
62    excluded := Union(excluded, [ "ExplicitHilbertSeries" ]);
63    # iterate over properties in alphabetical order, to reduce
64    # fluctuations between Normaliz versions
65    for prop in Set(NmzKnownConeProperties(cone)) do
66        if prop in excluded then
67            continue;
68        fi;
69        val := NmzConeProperty(cone, prop);
70        Print(prop," = ");
71        if IsMatrix(val) then
72            Print("\n");
73        fi;
74        Display(val);
75    od;
76end);
77
78InstallGlobalFunction( NmzBasisChange,
79function( cone )
80    local result;
81    result := NmzConeProperty( cone, "Sublattice" );
82    return rec(
83        Embedding := result[1],
84        Projection := result[2],
85        Annihilator := result[3],
86        );
87end );
88
89
90#
91#
92#
93InstallGlobalFunction("NmzCone", function(arg)
94    local func, opts_rec, opts_list, cone;
95    if Length(arg) = 1 then
96        if IsList(arg[1]) then
97            opts_list := arg[1];
98        #elif IsRecord(arg[1]) then
99        #   TODO
100        else
101            # TODO: better error message
102            Error("Unsupported input");
103        fi;
104    else
105        opts_list := arg;
106    fi;
107
108    cone := _NmzCone(opts_list);
109    return cone;
110end);
111
112# TODO: extend NmzCone to allow this syntax:
113##cone := NmzCone(rec(integral_closure := M, grading := [ 0, 0, 1 ]));;
114
115
116
117#
118#
119#
120InstallGlobalFunction("NmzCompute", function(arg)
121    local cone, propsToCompute;
122    if not Length(arg) in [1,2] then
123        Error("Wrong number of arguments, expected 1 or 2");
124        return fail;
125    fi;
126    cone := arg[1];
127    if not IsNormalizCone(cone) then
128        Error("First argument must be a Normaliz cone object");
129        return fail;
130    fi;
131    if Length(arg) = 1 then
132        propsToCompute := [];
133        if ValueOption("dual") = true then Add(propsToCompute, "DualMode"); fi;
134        if ValueOption("DualMode") = true then Add(propsToCompute, "DualMode"); fi;
135        if ValueOption("HilbertBasis") = true then Add(propsToCompute, "HilbertBasis"); fi;
136        # TODO: add more option names? or just support arbitrary ones, by using
137        # iterating over the (undocumented!) OptionsStack???
138        if Length(propsToCompute) = 0 then
139            propsToCompute := [ "DefaultMode" ];
140        fi;
141    else
142        if IsString(arg[2]) then
143            propsToCompute := [arg[2]];
144        else
145            propsToCompute := arg[2];
146        fi;
147    fi;
148    return _NmzCompute(cone, propsToCompute);
149end);
150