# We believe that most policies will have some sort of parity.

@prefix air: <http://dig.csail.mit.edu/TAMI/2007/amord/air#> .
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix s: <http://dig.csail.mit.edu/2009/IARPA-PIR/sparql#> .
@prefix : <http://dig.csail.mit.edu/2009/IARPA-PIR/policy#> .

# This prefix allows us to talk about abstract types.
@prefix type: <http://dig.csail.mit.edu/2009/IARPA-PIR/generic#> .

@forAll :Q, :P, :W, :V, :T, :F, :S, :U, :O.
@forAll :X, :Y, :Z, :A, :B, :C.

# Our attempt here is to catalog some generic types of queries, hoping to find
# patterns in their implementation that may allow us to make some claims.

# Here are some sample policies. Only ~A is stateless.
# ~A            May not view anything of type:A
#               Call this :Restriction (RX)
# A (+) B       May view anything of type:A OR type:B but never both.
#               Call this :Exclusion (EX)
# A <-> B       May only view type:A if also viewing type:B and vice-versa.
#               Implementation exhibits strong parity with inclusion.
#               Call this :Inclusion (IN)
# A -> ~B       If you have seen anything of type:A then you may not see
#               anything of type:B.
#               Call this :Blocking (BL)
# N-of(A,B,...) Assert that you've seen N items of type:A, type:B, etc.
#               Logically equivalent to a more complicated function.
#               Example: N-of(A,B,C) == (A&B)|(B&C)|(A&C)
#               Call this :Selection (SL)
#
# It would also be advantageous for us to support chaining of policies.
# Example: 3-of(A,B,C,D,E) -> ~F, selection causes blocking.

# For now, let's look at the simplest usage case: queries containing the SPARQL
# syntax: WHERE (?x type:A ?y)
# Most of the interesting part of each rule will happen in the part that checks
# the WHERE clause.
# There are several edge cases that we need to address in a complete policy.

:Blocking a air:Policy; # Using type:F and type:G.
    air:label "Blocking rule. Viewing one type prohibits viewing another type.";
    air:rule :BL_RULE01.

:BL_RULE01 a air:BeliefRule;
       air:label "Blocking query matching rule.";
       air:pattern {
	       :Q a s:Select;
           s:POSList :P;
           s:WhereClause :W.
       };
       air:description (:Q " is a SPARQL Query");
       air:rule :BL_RULE02.

:BL_RULE02 a air:BeliefRule;
       air:label "Blocking non-compliance rule 1.";
       air:pattern { 
             :W s:TriplePattern :T .
             :T log:includes { :X type:F :V }.
             :W s:TriplePattern :U.
             :U log:includes { :X type:G :C } .
       };
       air:description ("The query, " :Q  ", includes a reference to something of type:F and type:G in the WHERE clause.");
       air:assert { :Q air:non-compliant-with :Blocking };
       air:alt [ air:rule :BL_RULE02a ].

:BL_RULE02a a air:BeliefRule;
       air:label "Blocking non-compliance rule 1a - OPTIONAL clause.";
       air:pattern { 
             :W s:TriplePattern :T .
             :T log:includes { :X type:F :V }.
             :W s:OptionalGraphPattern :U.
             :U s:TriplePattern :O.
             :O log:includes { [] type:G [] }.
       };
       air:description ("The query, " :Q  ", includes a reference to something of type:F in WHERE and type:G in OPTIONAL.");
       air:assert { :Q air:non-compliant-with :Blocking };
       air:alt [ air:rule :BL_RULE03 ].

:BL_RULE03 a air:BeliefRule;
# Matches WHERE{?x type:B ?y . ?x type:C ?y}
       air:label "Blocking compliance rule.";
       air:pattern {
             :W s:TriplePattern :T .
             :T log:includes { :X type:F :V }.
        };
	   air:description (" The query, " :Q  ", includes a reference to type:F but not type:G in the WHERE clause, in compliance with the blocking policy." );
        air:assert { :Q air:compliant-with :Blocking };
        air:alt [ air:rule :BL_RULE03a ].

:BL_RULE03a a air:BeliefRule;
       air:label "Blocking compliance rule.";
       air:pattern {
             :W s:TriplePattern :T .
             :T log:includes { :X type:G :V }.
        };
	   air:description (" The query, " :Q  ", includes a reference to type:G but not type:F in the WHERE clause, in compliance with the blocking policy." );
        air:assert { :Q air:compliant-with :Blocking };
        air:alt [ air:rule :BL_RULE04 ].

:BL_RULE04 a air:BeliefRule;
    air:label "Blocking default rule.";
    air:pattern {};
    air:description (" The query, " :Q  ", does not include a reference to type:F or type:G in the WHERE clause." );
    air:assert { :Q air:compliant-with :Blocking }.


:Restriction a air:Policy; # Using type:A.
    air:label "Restriction rule. Prohibits viewing a particular type.";
    air:rule :RX_RULE01.

:RX_RULE01 a air:BeliefRule;
       air:label "Restriction query matching rule.";
       air:pattern {
	:Q a s:Select;
           s:POSList :P;
           s:WhereClause :W.
       };
        air:description (:Q " is a SPARQL Query");
        air:rule :RX_RULE02.

:RX_RULE02 a air:BeliefRule;
# Matches WHERE{?x type:A ?y}
       air:label "Restriction WHERE clause rule.";
        air:pattern {
             :P s:variable :V.
             :W s:TriplePattern :T.
             :T log:includes { :X type:A :V }
        };
	air:description ("The query, " :Q  ", accesses type:A in the where clause as a pattern, " :T ", and retrieves type:A values as variable," :V );
        air:assert { :Q air:non-compliant-with :Restriction };
        air:alt [ air:rule :RX_RULE03 ].

:RX_RULE03 a air:BeliefRule;
       air:label "Restriction OPTIONAL clause rule.";
       air:pattern {
             :W s:OptionalGraphPattern :O.
             :O s:TriplePattern :T.
             :T log:includes { [] type:A [] }
        };
        air:description ("The query, " :Q  ", includes reference to type:A in the OPTIONAL part of the WHERE clause"); 
        air:assert { :Q air:non-compliant-with :Restriction };
        air:alt [ air:rule :RX_RULE04 ].

:RX_RULE04 a air:BeliefRule;
       air:label "Restriction compliance rule.";
        air:pattern { 
             :W s:TriplePattern :T.
             :T log:notIncludes { [] type:A [] }
       };
        air:description ("The query, " :Q  ", does not includes reference to type:A.");
        air:assert { :Q air:compliant-with :Restriction }.


:Exclusion a air:Policy; # Using type:B and type:C.
    air:label "Restriction rule. Prohibits viewing a particular type.";
    air:rule :EX_RULE01.

:EX_RULE01 a air:BeliefRule;
       air:label "Exclusion query matching rule.";
       air:pattern {
	:Q a s:Select;
           s:POSList :P;
           s:WhereClause :W.
       };
        air:description (:Q " is a SPARQL Query");
        air:rule :EX_RULE02.

:EX_RULE02 a air:BeliefRule;
# Matches WHERE{?x type:B ?y . ?x type:C ?y}
       air:label "Exclusion WHERE clause rule.";
        air:pattern {
             :P s:variable :V.
             :W s:TriplePattern :T.
             :T log:includes { :X type:B :V } .
             :W s:TriplePattern :U.
             :U log:includes { :X type:C :C } .
        };
	air:description (" The query, " :Q  ", accesses type:B in the where clause as a pattern, " :T ", and retrieves type:C values as a variable, " :V ". It also accesses type:C in the same where clause as a pattern, " :U " and retrieves type:C values as a variable, " :C ". This policy allows one, or the other, but not both." );
        air:assert { :Q air:non-compliant-with :Exclusion };
        air:alt [ air:rule :EX_RULE02a ].

:EX_RULE02a a air:BeliefRule;
# Matches WHERE{?x type:B ?y . ?x type:C ?y}
       air:label "Exclusion WHERE clause rule.";
        air:pattern {
             :P s:variable :V.
             :W s:TriplePattern :T.
             :T log:includes { :X type:B :V } .
             :W s:OptionalGraphPattern :O.
             :O s:TriplePattern :U.
             :U log:includes { :X type:C :C }.
        };
	air:description (" The query, " :Q  ", accesses type:B in the where clause as a pattern, " :T ", and retrieves type:C values as a variable, " :V ". It also accesses type:C in the same OPTIONAL part of the where clause as a pattern, " :U " and retrieves type:C values as a variable, " :C ". This policy allows one, or the other, but not both." );
        air:assert { :Q air:non-compliant-with :Exclusion };
        air:alt [ air:rule :EX_RULE02b ].

:EX_RULE02b a air:BeliefRule;
# Matches WHERE{?x type:B ?y . ?x type:C ?y}
       air:label "Exclusion WHERE clause rule.";
        air:pattern {
             :P s:variable :V.
             :W s:TriplePattern :T.
             :T log:includes { :X type:C :V } .
             :W s:OptionalGraphPattern :O.
             :O s:TriplePattern :U.
             :U log:includes { :X type:B :C }.
        };
	air:description (" The query, " :Q  ", accesses type:C in the where clause as a pattern, " :T ", and retrieves type:C values as a variable, " :V ". It also accesses type:B in the same where clause as a pattern, " :U " and retrieves type:C values as a variable, " :C ". This policy allows one, or the other, but not both." );
        air:assert { :Q air:non-compliant-with :Exclusion };
        air:alt [ air:rule :EX_RULE03 ].

:EX_RULE03 a air:BeliefRule;
       air:label "Exclusion compliance rule 1.";
        air:pattern { 
             :W s:TriplePattern :T.
             :T log:notIncludes { [] type:B [] }.
       };
        air:description ("The query, " :Q  ", includes a reference to something of type:C, but not of type:B.");
        air:assert { :Q air:compliant-with :Exclusion };
        air:alt [ air:rule :EX_RULE04 ].

:EX_RULE04 a air:BeliefRule;
       air:label "Exclusion compliance rule 2.";
        air:pattern { 
             :W s:TriplePattern :T.
             :T log:notIncludes { [] type:C [] }.
       };
        air:description ("The query, " :Q  ", includes a reference to something of type:B, but not of type:C.");
        air:assert { :Q air:compliant-with :Exclusion }.



:Inclusion a air:Policy; # Using type:D and type:E.
    air:label "Restriction rule. Prohibits viewing a particular type.";
    air:rule :IN_RULE01.

:IN_RULE01 a air:BeliefRule;
       air:label "Inclusion query matching rule.";
       air:pattern {
	       :Q a s:Select;
           s:POSList :P;
           s:WhereClause :W.
       };
       air:description (:Q " is a SPARQL Query");
       air:rule :IN_RULE02.

:IN_RULE02 a air:BeliefRule;
       air:label "Inclusion compliance rule.";
       air:pattern { 
             :W s:TriplePattern :T.
             :T log:includes { [] type:D [] }.
             :W s:TriplePattern :U.
             :U log:includes { [] type:E [] }.
       };
       air:description (" IN_RULE02 The query, " :Q  ", includes a reference to something of type:D and of type:E.");
       air:assert { :Q air:compliant-with :Inclusion };
       air:alt [ air:rule :IN_RULE03 ].

:IN_RULE03 a air:BeliefRule;
       air:label "Inclusion non-compliance rule 1.";
       air:pattern { 
             :W s:TriplePattern :T.
             :T log:includes { [] type:D [] }.
       };
       air:description (" IN_RULE03 The query, " :Q  ", includes a reference to something of type:D, but not of type:E.");
       air:assert { :Q air:non-compliant-with :Inclusion };
       air:alt [ air:rule :IN_RULE04 ].

:IN_RULE04 a air:BeliefRule;
       air:label "Inclusion non-compliance rule 2.";
       air:pattern {
             :W s:TriplePattern :T.
             :T log:includes { [] type:E [] }
        };
	   air:description (" IN_RULE04 The query, " :Q  ", includes a reference to type:E, but not type:D." );
       air:assert { :Q air:non-compliant-with :Inclusion };
       air:alt [ air:rule :IN_RULE05 ].

:IN_RULE05 a air:BeliefRule;
       air:label "Inclusion compliance default rule.";
       air:pattern {};
       air:description (" IN_RULE05 The query, " :Q  ", does not refer to type:D or type:E.");
       air:assert { :Q air:compliant-with :Inclusion }.

#ends
