Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/libs/singular/option.pyx
8817 views
1
"""
2
libSingular: Options
3
4
Singular uses a set of global options to determine verbosity and the
5
behavior of certain algorithms. We provide an interface to these
6
options in the most 'natural' python-ic way. Users who do not wish to
7
deal with Singular functions directly usually do not have to worry
8
about this interface or Singular options in general since this is
9
taken care of by higher level functions.
10
11
We compute a Groebner basis for Cyclic-5 in two different contexts::
12
13
sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
14
sage: I = sage.rings.ideal.Cyclic(P)
15
sage: std = sage.libs.singular.ff.std
16
17
By default, tail reductions are performed::
18
19
sage: from sage.libs.singular.option import opt, opt_ctx
20
sage: opt['red_tail']
21
True
22
sage: std(I)[-1]
23
d^2*e^6 + 28*b*c*d + ...
24
25
If we don't want this, we can create an option context, which disables
26
this::
27
28
sage: with opt_ctx(red_tail=False, red_sb=False):
29
... std(I)[-1]
30
d^2*e^6 + 8*c^3 + ...
31
32
However, this does not affect the global state::
33
34
sage: opt['red_tail']
35
True
36
37
On the other hand, any assignment to an option object will immediately
38
change the global state::
39
40
sage: opt['red_tail'] = False
41
sage: opt['red_tail']
42
False
43
sage: opt['red_tail'] = True
44
sage: opt['red_tail']
45
True
46
47
Assigning values within an option context, only affects this context::
48
49
sage: with opt_ctx:
50
... opt['red_tail'] = False
51
52
sage: opt['red_tail']
53
True
54
55
Option contexts can also be safely stacked::
56
57
sage: with opt_ctx:
58
... opt['red_tail'] = False
59
... print opt
60
... with opt_ctx:
61
... opt['red_through'] = False
62
... print opt
63
...
64
general options for libSingular (current value 0x00000082)
65
general options for libSingular (current value 0x00000002)
66
67
sage: print opt
68
general options for libSingular (current value 0x02000082)
69
70
Furthermore, the integer valued options ``deg_bound`` and
71
``mult_bound`` can be used::
72
73
sage: R.<x,y> = QQ[]
74
sage: I = R*[x^3+y^2,x^2*y+1]
75
sage: opt['deg_bound'] = 2
76
sage: std(I)
77
[x^2*y + 1, x^3 + y^2]
78
sage: opt['deg_bound'] = 0
79
sage: std(I)
80
[y^3 - x, x^2*y + 1, x^3 + y^2]
81
82
The same interface is available for verbosity options::
83
84
sage: from sage.libs.singular.option import opt_verb
85
sage: opt_verb['not_warn_sb']
86
False
87
sage: opt.reset_default() # needed to avoid side effects
88
sage: opt_verb.reset_default() # needed to avoid side effects
89
90
AUTHOR:
91
92
- Martin Albrecht (2009-08): initial implementation
93
- Martin Albrecht (2010-01): better interface, verbosity options
94
- Simon King (2010-07): Python-ic option names; deg_bound and mult_bound
95
"""
96
#*****************************************************************************
97
# Copyright (C) 2010 Martin Albrecht <[email protected]>
98
#
99
# Distributed under the terms of the GNU General Public License (GPL)
100
# http://www.gnu.org/licenses/
101
#*****************************************************************************
102
103
from sage.libs.singular.decl cimport singular_options, singular_verbose_options, Kstd1_deg, Kstd1_mu
104
105
from sage.libs.singular.decl cimport OPT_PROT, OPT_REDSB, OPT_NOT_BUCKETS, OPT_NOT_SUGAR, OPT_SUGARCRIT, OPT_REDTHROUGH, OPT_DEGBOUND, OPT_MULTBOUND
106
from sage.libs.singular.decl cimport OPT_RETURN_SB, OPT_FASTHC, OPT_OLDSTD, OPT_REDTAIL, OPT_INTSTRATEGY, OPT_NOTREGULARITY
107
from sage.libs.singular.decl cimport OPT_WEIGHTM, Sy_bit
108
109
from sage.libs.singular.decl cimport V_SHOW_MEM, V_YACC, V_REDEFINE, V_READING, V_LOAD_LIB, V_DEBUG_LIB
110
from sage.libs.singular.decl cimport V_LOAD_PROC, V_DEF_RES, V_SHOW_USE, V_IMAP, V_PROMPT
111
from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT, V_DEG_STOP
112
113
_options_py_to_singular={'return_sb':'returnSB',
114
'fast_hc':'fastHC',
115
'inf_red_tail':'infRedTail',
116
'int_strategy':'intStrategy',
117
'not_regularity':'notRegularity',
118
'not_sugar':'notSugar',
119
'not_buckets':'notBuckets',
120
'qring_nf':'qringNF',
121
'redsb':'redSB',
122
'red_sb':'redSB',
123
'red_tail':'redTail',
124
'red_through':'redThrough',
125
'sugar_crit':'sugarCrit',
126
'weight_m':'weightM',
127
'content_sb':'contentSB',
128
'mult_bound':'multBound',
129
'deg_bound':'degBound',
130
'imap':'Imap',
131
'debug_lib':'debugLib',
132
'def_res':'defRes',
133
'load_lib':'loadLib',
134
'load_proc':'loadProc',
135
'not_warn_sb':'notWarnSB'}
136
137
cdef class LibSingularOptions_abstract:
138
"""
139
Abstract Base Class for libSingular options.
140
"""
141
cdef unsigned int *global_options
142
cdef object name
143
cdef object name_map
144
145
def __init__(self, **kwds):
146
"""
147
INPUT:
148
149
- ``**kwds`` - all keyword parameters are immediately applied.
150
151
EXAMPLE::
152
153
sage: from sage.libs.singular.option import LibSingularOptions
154
sage: opt = LibSingularOptions(redTail=False)
155
sage: opt['redTail']
156
False
157
sage: opt['redTail'] = True
158
sage: opt['redTail']
159
True
160
sage: opt['deg_bound'] = 2
161
162
The options can be named in Python or Singular style::
163
164
sage: opt['degBound']
165
2
166
"""
167
for k,v in kwds.iteritems():
168
self[k] = v
169
170
def __getitem__(self, name):
171
"""
172
EXAMPLE::
173
174
sage: from sage.libs.singular.option import opt
175
sage: opt['red_tail']
176
True
177
sage: opt['deg_bound'] = 2
178
179
The options can be named in Python or Singular style::
180
181
sage: opt['degBound']
182
2
183
sage: opt.reset_default() # needed to avoid side effects
184
"""
185
name = _options_py_to_singular.get(name,name)
186
if name == "degBound":
187
if bool(self.global_options[0] & self.name_map[name]):
188
return Kstd1_deg
189
return int(0)
190
if name == "multBound":
191
if bool(self.global_options[0] & self.name_map[name]):
192
return Kstd1_mu
193
return int(0)
194
try:
195
return bool(self.global_options[0] & self.name_map[name])
196
except KeyError:
197
raise NameError("Option '%s' unknown."%(name,))
198
199
def __setitem__(self, name, value):
200
"""
201
EXAMPLE::
202
203
sage: from sage.libs.singular.option import opt, opt_ctx
204
sage: opt['redTail']
205
True
206
sage: with opt_ctx:
207
... opt['redTail'] = False
208
... opt['redTail']
209
False
210
sage: opt['red_tail']
211
True
212
sage: opt.reset_default() # needed to avoid side effects
213
"""
214
name = _options_py_to_singular.get(name,name)
215
try:
216
if value:
217
self.global_options[0] = self.global_options[0] | self.name_map[name]
218
else:
219
self.global_options[0] = self.global_options[0] & ~self.name_map[name]
220
if name == 'degBound':
221
global Kstd1_deg
222
Kstd1_deg = value
223
elif name == 'multBound':
224
global Kstd1_mu
225
Kstd1_mu = value
226
except KeyError:
227
raise NameError("Option '%s' unknown."%(name,))
228
229
def __int__(self):
230
"""
231
EXAMPLE::
232
233
sage: from sage.libs.singular.option import opt
234
sage: hex(int(opt))
235
'0x6000082'
236
"""
237
return int(self.global_options[0])
238
239
def save(self):
240
"""
241
Return a triple of integers that allow reconstruction of the options.
242
243
EXAMPLE::
244
245
sage: from sage.libs.singular.option import opt
246
sage: opt['deg_bound']
247
0
248
sage: opt['red_tail']
249
True
250
sage: s = opt.save()
251
sage: opt['deg_bound'] = 2
252
sage: opt['red_tail'] = False
253
sage: opt['deg_bound']
254
2
255
sage: opt['red_tail']
256
False
257
sage: opt.load(s)
258
sage: opt['deg_bound']
259
0
260
sage: opt['red_tail']
261
True
262
sage: opt.reset_default() # needed to avoid side effects
263
"""
264
return (int(self.global_options[0]), self['deg_bound'], self['mult_bound'])
265
266
def load(self, value=None):
267
"""
268
EXAMPLE::
269
270
sage: from sage.libs.singular.option import opt as sopt
271
sage: bck = sopt.save(); hex(bck[0]), bck[1], bck[2]
272
('0x6000082', 0, 0)
273
sage: sopt['redTail'] = False
274
sage: hex(int(sopt))
275
'0x4000082'
276
sage: sopt.load(bck)
277
sage: sopt['redTail']
278
True
279
"""
280
if value == None:
281
value = (None,0,0)
282
self.global_options[0] = int(value[0])
283
global Kstd1_deg
284
global Kstd1_mu
285
Kstd1_deg = value[1]
286
Kstd1_mu = value[2]
287
288
def __repr__(self):
289
"""
290
EXAMPLE::
291
292
sage: from sage.libs.singular.option import opt as sopt
293
sage: sopt
294
general options for libSingular (current value 0x06000082)
295
"""
296
return "%s options for libSingular (current value 0x%08x)"%(self.name, self.global_options[0])
297
298
299
cdef class LibSingularOptions(LibSingularOptions_abstract):
300
"""
301
Pythonic Interface to libSingular's options.
302
303
Supported options are:
304
305
- ``return_sb`` or ``returnSB`` - the functions ``syz``,
306
``intersect``, ``quotient``, ``modulo`` return a standard
307
base instead of a generating set if ``return_sb``
308
is set. This option should not be used for ``lift``.
309
310
- ``fast_hc`` or ``fastHC`` - tries to find the highest corner
311
of the staircase (HC) as fast as possible during a standard
312
basis computation (only used for local orderings).
313
314
- ``int_strategy`` or ``intStrategy`` - avoids division of
315
coefficients during standard basis computations. This option
316
is ring dependent. By default, it is set for rings with
317
characteristic 0 and not set for all other rings.
318
319
- ``lazy`` - uses a more lazy approach in std computations, which
320
was used in SINGULAR version before 2-0 (and which may lead to
321
faster or slower computations, depending on the example).
322
323
- ``length`` - select shorter reducers in std computations.
324
325
- ``not_regularity`` or ``notRegularity`` - disables the
326
regularity bound for ``res`` and ``mres``.
327
328
- ``not_sugar`` or ``notSugar`` - disables the sugar strategy
329
during standard basis computation.
330
331
- ``not_buckets`` or ``notBuckets`` - disables the bucket
332
representation of polynomials during standard basis
333
computations. This option usually decreases the memory
334
usage but increases the computation time. It should only
335
be set for memory-critical standard basis computations.
336
337
- ``old_std`` or ``oldStd`` - uses a more lazy approach in std
338
computations, which was used in SINGULAR version before 2-0
339
(and which may lead to faster or slower computations, depending
340
on the example).
341
342
- ``prot`` - shows protocol information indicating the progress
343
during the following computations: ``facstd``, ``fglm``,
344
``groebner``, ``lres``, ``mres``, ``minres``, ``mstd``,
345
``res``, ``slimgb``, ``sres``, ``std``, ``stdfglm``,
346
``stdhilb``, ``syz``.
347
348
- `red_sb`` or ``redSB`` - computes a reduced standard basis in
349
any standard basis computation.
350
351
- ``red_tail`` or ``redTail`` - reduction of the tails of
352
polynomials during standard basis computations. This option
353
is ring dependent. By default, it is set for rings with global
354
degree orderings and not set for all other rings.
355
356
- ``red_through`` or ``redThrough`` - for inhomogenous input,
357
polynomial reductions during standard basis computations are
358
never postponed, but always finished through. This option is
359
ring dependent. By default, it is set for rings with global
360
degree orderings and not set for all other rings.
361
362
- ``sugar_crit`` or ``sugarCrit`` - uses criteria similar to the
363
homogeneous case to keep more useless pairs.
364
365
- ``weight_m`` or ``weightM`` - automatically computes suitable
366
weights for the weighted ecart and the weighted sugar method.
367
368
In addition, two integer valued parameters are supported, namely:
369
370
- ``deg_bound`` or ``degBound`` - The standard basis computation
371
is stopped if the total (weighted) degree exceeds ``deg_bound``.
372
``deg_bound`` should not be used for a global ordering with
373
inhomogeneous input. Reset this bound by setting ``deg_bound``
374
to 0. The exact meaning of "degree" depends on the ring odering
375
and the command: ``slimgb`` uses always the total degree with
376
weights 1, ``std`` does so for block orderings, only.
377
378
- ``mult_bound`` or ``multBound`` - The standard basis computation
379
is stopped if the ideal is zero-dimensional in a ring with local
380
ordering and its multiplicity is lower than ``mult_bound``.
381
Reset this bound by setting ``mult_bound`` to 0.
382
383
EXAMPLE::
384
385
sage: from sage.libs.singular.option import LibSingularOptions
386
sage: libsingular_options = LibSingularOptions()
387
sage: libsingular_options
388
general options for libSingular (current value 0x06000082)
389
390
Here we demonstrate the intended way of using libSingular options::
391
392
sage: R.<x,y> = QQ[]
393
sage: I = R*[x^3+y^2,x^2*y+1]
394
sage: I.groebner_basis(deg_bound=2)
395
[x^3 + y^2, x^2*y + 1]
396
sage: I.groebner_basis()
397
[x^3 + y^2, x^2*y + 1, y^3 - x]
398
399
The option ``mult_bound`` is only relevant in the local case::
400
401
sage: from sage.libs.singular.option import opt
402
sage: Rlocal.<x,y,z> = PolynomialRing(QQ, order='ds')
403
sage: x^2<x
404
True
405
sage: J = [x^7+y^7+z^6,x^6+y^8+z^7,x^7+y^5+z^8, x^2*y^3+y^2*z^3+x^3*z^2,x^3*y^2+y^3*z^2+x^2*z^3]*Rlocal
406
sage: J.groebner_basis(mult_bound=100)
407
[x^3*y^2 + y^3*z^2 + x^2*z^3, x^2*y^3 + x^3*z^2 + y^2*z^3, y^5, x^6 + x*y^4*z^5, x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3, z^6 - x*y^4*z^4 - x^3*y*z^5]
408
sage: opt['red_tail'] = True # the previous commands reset opt['red_tail'] to False
409
sage: J.groebner_basis()
410
[x^3*y^2 + y^3*z^2 + x^2*z^3, x^2*y^3 + x^3*z^2 + y^2*z^3, y^5, x^6, x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3, z^6, y^4*z^3 - y^3*z^4 - x^2*z^5, x^3*y*z^4 - x^2*y^2*z^4 + x*y^3*z^4, x^3*z^5, x^2*y*z^5 + y^3*z^5, x*y^3*z^5]
411
412
"""
413
def __init__(self, **kwds):
414
"""
415
Create a new option interface.
416
417
EXAMPLE::
418
419
sage: from sage.libs.singular.option import LibSingularOptions
420
sage: libsingular_options = LibSingularOptions()
421
sage: libsingular_options
422
general options for libSingular (current value 0x...)
423
"""
424
self.global_options = &singular_options
425
self.name = "general"
426
self.name_map = {"prot": Sy_bit(OPT_PROT),
427
"redSB": Sy_bit(OPT_REDSB),
428
"notBuckets": Sy_bit(OPT_NOT_BUCKETS),
429
"notSugar": Sy_bit(OPT_NOT_SUGAR),
430
"sugarCrit": Sy_bit(OPT_SUGARCRIT),
431
"redThrough": Sy_bit(OPT_REDTHROUGH),
432
"returnSB": Sy_bit(OPT_RETURN_SB),
433
"fastHC": Sy_bit(OPT_FASTHC),
434
"oldStd": Sy_bit(OPT_OLDSTD),
435
"redTail": Sy_bit(OPT_REDTAIL),
436
"intStrategy": Sy_bit(OPT_INTSTRATEGY),
437
"notRegularity": Sy_bit(OPT_NOTREGULARITY),
438
"weightM": Sy_bit(OPT_WEIGHTM),
439
"degBound": Sy_bit(OPT_DEGBOUND),
440
"multBound": Sy_bit(OPT_MULTBOUND)}
441
LibSingularOptions_abstract.__init__(self, **kwds)
442
443
def reset_default(self):
444
"""
445
Reset libSingular's default options.
446
447
EXAMPLE::
448
449
sage: from sage.libs.singular.option import opt
450
sage: opt['red_tail']
451
True
452
sage: opt['red_tail'] = False
453
sage: opt['red_tail']
454
False
455
sage: opt['deg_bound']
456
0
457
sage: opt['deg_bound'] = 2
458
sage: opt['deg_bound']
459
2
460
sage: opt.reset_default()
461
sage: opt['red_tail']
462
True
463
sage: opt['deg_bound']
464
0
465
"""
466
from sage.libs.singular.singular import _saved_options
467
self.load(_saved_options)
468
469
470
471
#############
472
473
cdef class LibSingularVerboseOptions(LibSingularOptions_abstract):
474
"""
475
Pythonic Interface to libSingular's verbosity options.
476
477
Supported options are:
478
479
- ``mem`` - shows memory usage in square brackets.
480
- ``yacc`` - Only available in debug version.
481
- ``redefine`` - warns about variable redefinitions.
482
- ``reading`` - shows the number of characters read from a file.
483
- ``loadLib`` or ``load_lib`` - shows loading of libraries.
484
- ``debugLib`` or ``debug_lib`` - warns about syntax errors
485
when loading a library.
486
- ``loadProc`` or ``load_proc`` - shows loading of procedures
487
from libraries.
488
- ``defRes`` or ``def_res`` - shows the names of the syzygy
489
modules while converting ``resolution`` to ``list``.
490
- ``usage`` - shows correct usage in error messages.
491
- ``Imap`` or ``imap`` - shows the mapping of variables with
492
the ``fetch`` and ``imap`` commands.
493
- ``notWarnSB`` or ``not_warn_sb`` - do not warn if
494
a basis is not a standard basis
495
- ``contentSB`` or ``content_sb`` - avoids to divide by the
496
content of a polynomial in ``std`` and related algorithms.
497
Should usually not be used.
498
- ``cancelunit`` - avoids to divide polynomials by non-constant
499
units in ``std`` in the local case. Should usually not be used.
500
501
EXAMPLE::
502
503
sage: from sage.libs.singular.option import LibSingularVerboseOptions
504
sage: libsingular_verbose = LibSingularVerboseOptions()
505
sage: libsingular_verbose
506
verbosity options for libSingular (current value 0x00002851)
507
"""
508
def __init__(self, **kwds):
509
"""
510
Create a new option interface.
511
512
EXAMPLE::
513
514
sage: from sage.libs.singular.option import LibSingularVerboseOptions
515
sage: libsingular_verb_options = LibSingularVerboseOptions()
516
sage: libsingular_verb_options
517
verbosity options for libSingular (current value 0x00002851)
518
"""
519
self.global_options = &singular_verbose_options
520
self.name = "verbosity"
521
self.name_map = {"mem": Sy_bit(V_SHOW_MEM),
522
"yacc": Sy_bit(V_YACC),
523
"redefine": Sy_bit(V_REDEFINE),
524
"reading": Sy_bit(V_READING),
525
"loadLib": Sy_bit(V_LOAD_LIB),
526
"debugLib": Sy_bit(V_DEBUG_LIB),
527
"loadProc": Sy_bit(V_LOAD_PROC),
528
"defRes": Sy_bit(V_DEF_RES),
529
"usage": Sy_bit(V_SHOW_USE),
530
"Imap": Sy_bit(V_IMAP),
531
"prompt": Sy_bit(V_PROMPT),
532
"notWarnSB":Sy_bit(V_NSB),
533
"contentSB":Sy_bit(V_CONTENTSB),
534
"cancelunit":Sy_bit(V_CANCELUNIT),
535
}
536
LibSingularOptions_abstract.__init__(self, **kwds)
537
538
def reset_default(self):
539
"""
540
Return to libSingular's default verbosity options
541
542
EXAMPLE::
543
544
sage: from sage.libs.singular.option import opt_verb
545
sage: opt_verb['not_warn_sb']
546
False
547
sage: opt_verb['not_warn_sb'] = True
548
sage: opt_verb['not_warn_sb']
549
True
550
sage: opt_verb.reset_default()
551
sage: opt_verb['not_warn_sb']
552
False
553
554
"""
555
from sage.libs.singular.singular import _saved_verbose_options
556
self.global_options[0] = int(_saved_verbose_options)
557
558
cdef class LibSingularOptionsContext:
559
"""
560
Option context
561
562
This object localizes changes to options.
563
564
EXAMPLE::
565
566
sage: from sage.libs.singular.option import opt, opt_ctx
567
sage: opt
568
general options for libSingular (current value 0x06000082)
569
570
::
571
572
sage: with opt_ctx(redTail=False):
573
... print opt
574
... with opt_ctx(redThrough=False):
575
... print opt
576
...
577
general options for libSingular (current value 0x04000082)
578
general options for libSingular (current value 0x04000002)
579
580
sage: print opt
581
general options for libSingular (current value 0x06000082)
582
"""
583
cdef list bck
584
cdef list bck_degBound
585
cdef list bck_multBound
586
cdef public LibSingularOptions_abstract opt
587
cdef object options
588
589
def __init__(self, LibSingularOptions_abstract opt, **kwds):
590
"""
591
Create a new context.
592
593
EXAMPLE::
594
595
sage: from sage.libs.singular.option import LibSingularOptionsContext, opt
596
sage: LibSingularOptionsContext(opt)
597
general options context for libSingular
598
"""
599
self.bck = []
600
self.bck_degBound = []
601
self.bck_multBound = []
602
self.options = kwds
603
self.opt = opt
604
605
def __enter__(self):
606
"""
607
EXAMPLE::
608
609
sage: from sage.libs.singular.option import opt, opt_ctx
610
sage: opt['redTail']
611
True
612
sage: with opt_ctx(redTail=False):
613
... opt['redTail']
614
False
615
"""
616
self.bck.append(self.opt.global_options[0])
617
self.bck_degBound.append(Kstd1_deg)
618
self.bck_multBound.append(Kstd1_mu)
619
opt = self.opt.__class__()
620
for k,v in self.options.iteritems():
621
opt[k] = v
622
623
def __call__(self, **kwds):
624
"""
625
Return a new option context where ``**kwds`` are applied.
626
627
EXAMPLE::
628
629
sage: from sage.libs.singular.option import opt, opt_ctx
630
sage: opt['redTail']
631
True
632
sage: with opt_ctx(redTail=False):
633
... opt['redTail']
634
False
635
"""
636
new = self.__class__(self.opt, **kwds)
637
return new
638
639
def __exit__(self, typ, value, tb):
640
"""
641
EXAMPLE::
642
643
sage: from sage.libs.singular.option import opt, opt_ctx
644
sage: opt['redTail']
645
True
646
sage: with opt_ctx(redTail=False):
647
... opt['redTail']
648
False
649
"""
650
self.opt.global_options[0] = self.bck.pop()
651
global Kstd1_deg
652
global Kstd1_mu
653
Kstd1_deg = self.bck_degBound.pop()
654
Kstd1_mu = self.bck_multBound.pop()
655
656
def __repr__(self):
657
"""
658
EXAMPLE::
659
660
sage: from sage.libs.singular.option import opt_ctx
661
sage: opt_ctx
662
general options context for libSingular
663
"""
664
return "%s options context for libSingular"%(self.opt.name)
665
666
667
opt = LibSingularOptions()
668
opt.reset_default()
669
opt_verb = LibSingularVerboseOptions()
670
opt_verb.reset_default()
671
opt_ctx = LibSingularOptionsContext(opt)
672
opt_verb_ctx = LibSingularOptionsContext(opt_verb)
673
674