# Blocking based on conditional filtering.
# Sample policy scenario: can't see a minor's name.
# Any query that asks for name needs to somehow filter for
# birthyear < 1991.
#
# This really requires us to implement a new primitive:
# A -> B        Call this :Requirement (:RQ)
#               We must do A in order to see B.
# In this case, A is "filter for minors" and B is "anything".

@prefix air: <http://dig.csail.mit.edu/TAMI/2007/amord/air#>.
@prefix s: <http://dig.csail.mit.edu/2009/IARPA-PIR/sparql#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix type: <http://dig.csail.mit.edu/2009/IARPA-PIR/generic#> .
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
@prefix : <>.

@forAll :Q, :P, :W, :F, :T, :A, :B, :X, :Y, :V, :R, :S, :G.

:retrieve-and-filter-policy a air:Policy;
	air:label "Retrieval-Filter Policy";
	air:rule :filter-retrieve-rule1.

:filter-retrieve-rule1 a air:BeliefRule;
	air:label "Filter and Retrieval Rule 1";
	air:pattern {
		:Q a s:Select;
		s:POSList :P;
		s:WhereClause :W.
	};
	air:description ("Make sure this is a query.");
	air:rule :filter-retrieve-rule2.

:filter-retrieve-rule2 a air:BeliefRule;
    air:label "Filter and retrieval name rule 2";
    air:pattern {
        :W s:TriplePattern :T.
        :T log:includes { [] type:firstlast [] } .
    };
    air:description ("Only check a query that asks for firstlast in WHERE (for now).");
    air:rule :filter-retrieve-rule4;
    air:alt [air:assert { :Q air:compliant-with :retrieve-and-filter-policy }].

# We need three checks here: upwards, downwards, range.
#
# Upwards example: birthyear > 1990 (includes minors and adults)
# Always fails since there is no way to make this kind of query restrict
# to minors unless there is a corresponding '<'.
#
# Downwards example: birthyear < 2009 (includes minors and adults)
# Check for math:lessThan :Y and :Y math:greaterThan 1991 for compliance.
#
# What happens when a user specifies a range? I think we can handle this using
# just the two rules below. A range would be something like 1985 < year < 1991.
# This will just break down into a '<' and a '>' part. As long as the '<' part
# is sane and in compliance with our rules, we're fine. If there is a '<' that
# restricts us to minors, it is strong enough that we have automatic compliance.
# If not, we have automatic non-compliance... so, really, we only need one rule,
# and that's rule 4. We will leave rule 3 in place for now because storage is
# cheap.

#:filter-retrieve-rule3 a air:BeliefRule;
#	air:label "Filter and Retrieval Rule 3";
#	air:pattern {
#		:W s:Filter :F.
##		:F log:includes {[] s:greaterThan []}. #DEBUG
#        :F s:TriplePattern :R.
#		:R log:includes {[] s:greaterThan []}.
#	};
#	air:description ("Upwards check.");
#	air:assert{:Q air:non-compliant-with :retrieve-and-filter-policy};
#	air:alt[ air:rule :filter-retrieve-rule4 ].
##    air:alt [air:assert { :Q air:compliant-with :retrieve-and-filter-policy }].

:filter-retrieve-rule4 a air:BeliefRule;
	air:label "Filter and Retrieval Rule 4";
	air:description ( :Y " year in Downwards check.");
	air:pattern{
		:W s:Filter :G.
        :G s:TriplePattern :S.
		:S log:includes { [] s:lessThan :Y}.
 #      :Y math:lessThan "1991"^^xsd:integer .
#       TODO: determine the current year automatically!
        :Y math:lessThan 1991 .
	};
	air:assert{:Q air:compliant-with :retrieve-and-filter-policy};
	air:alt[air:assert{ :Q air:non-compliant-with :retrieve-and-filter-policy};].
