[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 9afbf36 1/5: Assert more input-sequence invar
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 9afbf36 1/5: Assert more input-sequence invariants |
Date: |
Tue, 28 Feb 2017 19:40:46 -0500 (EST) |
branch: master
commit 9afbf36e1635ddf1c62444bb19ae0db54c6d4f3d
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Assert more input-sequence invariants
Added assertions to validate newly-formulated invariants having to do
with an interval's begin and end modes. Documented a particular nuance
and added a unit test to demonstrate it.
---
input_sequence.cpp | 35 +++++++++++++++++++++++++++++++++++
input_sequence_test.cpp | 16 +++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/input_sequence.cpp b/input_sequence.cpp
index 1f27dd5..e4b5286 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -611,6 +611,21 @@ void realize_intervals
/// [0, years_to_maturity). Cf. fill_interval_gaps(), which similarly
/// establishes only this weaker invariant, which also happens to be
/// what InputSequenceEntry asserts.
+///
+/// It is also asserted that begin and end modes are rational--which
+/// is a subtle concept. When no duration is explicitly specified, the
+/// next interval "inherits" its begin mode from a preceding interval.
+/// Thus, in this example:
+/// 0 retirement; 1000; 0 maturity
+/// the third interval's begin mode is e_retirement ("inherited" from
+/// the first interval's end mode): it begins at the retirement age
+/// incremented by one (one being the width of the second interval).
+/// Similarly, in this example:
+/// 1; 2; 3
+/// the second interval's begin mode is e_inception: it begins at
+/// inception plus an offset of one. The "mode" means not that begins
+/// at inception, but at a point based on inception. This explains why
+/// e_inception may be the begin mode of a postinitial interval.
void assert_sane_and_ordered_partition
(std::vector<ValueInterval> const& intervals
@@ -644,6 +659,26 @@ void assert_sane_and_ordered_partition
}
prior_end_duration = i.end_duration;
}
+
+ for(auto j = intervals.begin(); j != intervals.end(); ++j)
+ {
+ if(intervals.begin() == j || (intervals.end() - 1) == j)
+ {
+ // front() and back(): see assertions above.
+ continue;
+ }
+ else
+ {
+ LMI_ASSERT(e_invalid_mode != j->begin_mode);
+// ...no... LMI_ASSERT(e_inception != j->begin_mode); // Documented above.
+ LMI_ASSERT(e_inforce != j->begin_mode);
+ LMI_ASSERT(e_maturity != j->begin_mode);
+ LMI_ASSERT(e_invalid_mode != j->end_mode);
+ LMI_ASSERT(e_inception != j->end_mode);
+ LMI_ASSERT(e_inforce != j->end_mode);
+ LMI_ASSERT(e_maturity != j->end_mode);
+ }
+ }
}
} // Unnamed namespace.
diff --git a/input_sequence_test.cpp b/input_sequence_test.cpp
index b966f78..1721cfa 100644
--- a/input_sequence_test.cpp
+++ b/input_sequence_test.cpp
@@ -599,10 +599,24 @@ void input_sequence_test::test()
check(__FILE__, __LINE__, n, d, e, g);
InputSequence const seq(e, 10, 90, 95, 0, 2002);
std::vector<ValueInterval> const& i(seq.intervals());
+ }
+
+ // Duration keywords, with a one-time-only event at retirement.
+ {
+ int const n = 10;
+ double const d[n] = {0, 0, 0, 0, 0, 1000, 0, 0, 0, 0};
+ std::string const e("0 retirement; 1000; 0 maturity");
+ census += e + "\t\t\t\n";
+ std::string const g("0 retirement; 1000 6; 0");
+ check(__FILE__, __LINE__, n, d, e, g);
+ InputSequence const seq(e, 10, 90, 95, 0, 2002);
+ std::vector<ValueInterval> const& i(seq.intervals());
BOOST_TEST_EQUAL(e_inception , i[0].begin_mode);
BOOST_TEST_EQUAL(e_retirement, i[0].end_mode );
BOOST_TEST_EQUAL(e_retirement, i[1].begin_mode);
- BOOST_TEST_EQUAL(e_maturity , i[1].end_mode );
+ BOOST_TEST_EQUAL(e_duration , i[1].end_mode );
+ BOOST_TEST_EQUAL(e_retirement, i[2].begin_mode);
+ BOOST_TEST_EQUAL(e_maturity , i[2].end_mode );
}
// Test a simple parser error.