________________________________________________________________________

This file is part of Logtalk <https://logtalk.org/>  
SPDX-FileCopyrightText: 1998-2026 Paulo Moura <pmoura@logtalk.org>  
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
________________________________________________________________________


`intervals`
===========

This library provides:

- an `interval_protocol` protocol and an `interval` object implementing
    the 13 Allen base interval relations plus interval pair classification
    using `relation/3`

- an `interval_algebra_protocol` protocol and an `interval_algebra` object
	implementing Allen relation algebra predicates over the 13 base relation
	atoms

- an `interval_relation_set_protocol` protocol and an `interval_relation_set`
    object implementing canonical relation-set operations over Allen base
    relation atoms

- an `interval_constraint_network_protocol` protocol and an
	`interval_constraint_network` object implementing first interval
	constraint-network predicates over canonical relation sets, including
	batch refinement, explanation lists, and network
	inspection/comparison helpers

The `interval` object works on interval terms represented as `i(Start, End)`.
The `interval_algebra` object works on relation atoms such as `before`,
`overlaps`, and `contains`. The `interval_relation_set` object works on
canonical ordered duplicate-free lists of relation atoms. The
`interval_constraint_network` object works on `network(Nodes, Constraints)`
terms whose pair constraints are relation sets. Internally, the
`interval_constraint_network` object compiles that public representation to an
a dense indexed form for propagation and for most query operations, while still
returning ordinary `network/2` terms at the API boundary.

The `interval_algebra::compose/3` predicate returns canonical ordered
duplicate-free lists of base relation atoms.


Practical limits
----------------

The `interval_constraint_network` object is intended for small-to-medium symbolic
networks. It uses a complete `network(Nodes, Constraints)` representation, so the
number of stored pair constraints grows quadratically with the number of nodes.
Propagation is based on path consistency and now uses an internal dense indexed
representation with direct pair access, a reverse node-to-index table, and
scheduled-pair tracking to avoid repeated linear worklist duplicate checks.
This substantially reduces overhead relative to a purely list-based
implementation, but the representation is still dense and updates still rebuild
parts of the internal matrix before the result is decompiled back to a public
`network/2` term.

In practice, the network predicates are suitable for moderate qualitative temporal
reasoning workloads, but they should not be treated as a large-scale or
latency-sensitive temporal CSP solver. Exact limits depend on the Prolog backend,
network density, how often closure is recomputed, and how often callers invoke
single-step API operations that must compile or decompile the public network
representation.


API documentation
-----------------

Open the [../../apis/library_index.html#intervals](../../apis/library_index.html#intervals)
link in a web browser.


Loading
-------

To load all entities in this library, load the `loader.lgt` file:

	| ?- logtalk_load(intervals(loader)).


Testing
-------

To test this library predicates, load the `tester.lgt` file:

	| ?- logtalk_load(intervals(tester)).


Examples
--------

Classify two valid intervals according to their unique Allen base relation:

	| ?- interval::new(1, 3, I1), interval::new(3, 5, I2), interval::relation(I1, I2, Relation).
	Relation = meets.

Compose two Allen base relation atoms:

	| ?- interval_algebra::compose(meets, met_by, Relations).
	Relations = [finishes, finished_by, equal].

Normalize an Allen relation set:

	| ?- interval_relation_set::normalize([during, before, during], RelationSet).
	RelationSet = [before, during].

Propagate interval constraints across a small symbolic network:

	| ?- interval_constraint_network::new([a, b, c], Network0),
	     interval_constraint_network::refine(Network0, a, b, [before], Network1),
	     interval_constraint_network::refine(Network1, b, c, [before], Network2),
	     interval_constraint_network::path_consistency(Network2, Network3),
	     interval_constraint_network::relation(Network3, a, c, RelationSet).
	RelationSet = [before].

Check whether a query is entailed by the current symbolic constraints:

	| ?- interval_constraint_network::entails(Network3, a, c, [before, meets]).
	true.

Inspect a simple explanation for an entailed relation:

	| ?- interval_constraint_network::entails(Network3, a, c, [before], Explanation).
	Explanation = propagated(b, [before], [before], [before]).

Inspect a simple contradiction explanation after closure:

	| ?- interval_constraint_network::contradiction(Closure, Explanation).
	Explanation = contradiction(a, c, propagated(b, [before], [before], [before])).

Refine and propagate in a single operation that fails on contradiction:

	| ?- interval_constraint_network::new([a, b, c], Network0),
	     interval_constraint_network::refine_propagate(Network0, a, b, [before], Network1).
	Network1 = ...

Post a batch of constraints and propagate them in one step:

	| ?- interval_constraint_network::refine_propagate(Network0, [constraint(a, b, [before]), constraint(b, c, [before])], Network1).
	Network1 = ...

Collect direct and propagated changes while propagating:

	| ?- interval_constraint_network::propagate(Network2, Network3, Changes).
	Changes = [...].

Query which node triples caused the propagated refinements:

	| ?- interval_constraint_network::propagation_triples(Changes, Triples).
	Triples = [triple(a, b, c)].

List all immediate explanations supporting an entailed query:

	| ?- interval_constraint_network::entailment_explanations(Network3, a, c, [before, meets], Explanations).
	Explanations = [propagated(b, [before], [before], [before])].

List all contradiction explanations currently present in an inconsistent network:

	| ?- interval_constraint_network::contradiction_explanations(Closure, Explanations).
	Explanations = [...].

Inspect a closure and compare networks by generality or equivalence:

	| ?- interval_constraint_network::constraints(Network3, Constraints).
	Constraints = [constraint(a, b, [before]), constraint(a, c, [before]), constraint(b, c, [before])].

	| ?- interval_constraint_network::subsumes(Network0, Network3).
	true.

	| ?- interval_constraint_network::equivalent(Network3, Network5).
	true.
