Skip to content

Commit caaf519

Browse files
author
Kasper Peeters
committed
Tighten conditions on when to accept integer values and sequence values for Indices.
1 parent 1be1662 commit caaf519

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

core/properties/Indices.cc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
using namespace cadabra;
1010

11+
#define MAX_INTEGER_RANGE 100
12+
1113
Indices::Indices()
1214
: position_type(free)
1315
{
@@ -66,24 +68,30 @@ bool Indices::parse(Kernel& kernel, std::shared_ptr<Ex> ex, keyval_t& keyvals)
6668
else if(ki->first=="values") {
6769
//std::cerr << "got values keyword " << *(ki->second->name) << std::endl;
6870
if(*ki->second->name=="\\sequence") {
71+
// Only accept a sequence if both start and end are explicit integers.
72+
Ex::sibling_iterator sqit1 = Ex::begin(ki->second);
73+
Ex::sibling_iterator sqit2 = sqit1;
74+
++sqit2;
75+
if(!sqit1->is_integer() || !sqit2->is_integer())
76+
throw ConsistencyException("Value sequence for Indices property not explicit integers.");
77+
6978
auto args = std::make_shared<cadabra::Ex>(ki->second);
7079
auto prop = new Integer();
7180
kernel.inject_property(prop, ex, args);
7281

73-
if (prop->from.is_integer() && prop->to.is_integer()) {
74-
if (prop->difference.to_integer() < 100) {
75-
for (int i=prop->from.to_integer(); i<=prop->to.to_integer(); ++i) {
76-
values.push_back(Ex(i));
77-
}
78-
}
79-
}
82+
if(prop->difference.to_integer() > MAX_INTEGER_RANGE)
83+
throw ConsistencyException("Value sequence for Indices property spans too many elements.");
8084

85+
for (int i=prop->from.to_integer(); i<=prop->to.to_integer(); ++i) {
86+
values.push_back(Ex(i));
87+
}
88+
8189
++ki;
8290
continue;
8391
}
8492

8593
collect_index_values(ki->second);
86-
// If all values are indices, add an `Integer' property for the object,
94+
// If all values are integers, add an `Integer' property for the object,
8795
// listing these integers.
8896
bool is_number=true;
8997
bool is_continuous=false;
@@ -98,7 +106,7 @@ bool Indices::parse(Kernel& kernel, std::shared_ptr<Ex> ex, keyval_t& keyvals)
98106
});
99107
is_continuous = (int)values.size() == (values[values.size() - 1].to_integer() - values[0].to_integer() + 1);
100108
}
101-
// FIXME: do not apply Integer to a list of integers with gaps as
109+
// Do not apply Integer to a list of integers with gaps as
102110
// the former can only deal with continuous ranges.
103111
if(is_continuous) {
104112
// std::cerr << "Injecting Integer property" << std::endl;

tests/dummies.cdb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,26 @@ test06()
9090

9191
def test07():
9292
__cdbkernel__ = create_scope()
93+
try:
94+
{r, s}::Indices(values={-1..a}).
95+
sys.exit(-1)
96+
except:
97+
print("Test 07a passed")
98+
try:
99+
{r, s}::Indices(values={-1..999}).
100+
sys.exit(-1)
101+
except:
102+
print("Test 07b passed")
93103
{a, b}::Indices(values={-1..2}).
94104
{c, d}::Indices(values={-1,1,2}).
95105
\delta{#}::KroneckerDelta.
96106
ex1 := \delta_{a b} \delta_{a b}.
97107
eliminate_kronecker(ex1)
98108
assert ex1 == 4
109+
print("Test 07c passed")
99110
ex2 := \delta_{c d} \delta_{c d}.
100111
eliminate_kronecker(ex2)
101112
assert ex2 == $\delta_{d d}$
102-
print("Test 07 passed")
113+
print("Test 07d passed")
103114

104115
test07()

0 commit comments

Comments
 (0)