# Gray Code Counter
# See https://en.wikipedia.org/wiki/Gray_code
# Taken from the book "Clause and Effect" Chapter 8

@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix : <http://example.org/ns#>.

(0 0) :and 0.
(0 1) :and 0.
(1 0) :and 0.
(1 1) :and 1.

(0 0) :or 0.
(0 1) :or 1.
(1 0) :or 1.
(1 1) :or 1.

0 :inv 1.
1 :inv 0.

(_:D _:Q) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:D 0 _:Q) :dff _:Q.
    }.
}.

(_:D _:Q) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:D 1 _:Q) :dff _:D.
    }.
}.

(_:A _:B _:Q _:T1 _:NA _:NB _:T2) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:A _:B) :neta _:Q.
    }.
    (_:A _:B) :and _:T1.
    _:A :inv _:NA.
    _:B :inv _:NB.
    (_:NA _:NB) :and _:T2.
    (_:T1 _:T2) :or _:Q.
}.

(_:A _:B _:C _:Q1 _:Q2 _:T1 _:NC _:T2 _:NA _:T3) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:A _:B _:C) :netb (_:Q1 _:Q2).
    }.
    (_:A _:C) :and _:T1.
    _:C :inv _:NC.
    (_:B _:NC) :and _:T2.
    _:A :inv _:NA.
    (_:NA _:C) :and _:T3.
    (_:T1 _:T2) :or _:Q1.
    (_:T2 _:T3) :or _:Q2.
}.


(_:C _:Qa _:Qb _:Qc _:Za _:Zb _:Zc _:D1 _:D2 _:D3) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:C (_:Qa _:Qb _:Qc)) :gcc (_:Za _:Zb _:Zc).
    }.
    (_:Qa _:Qb _:Qc) :netb (_:D1 _:D2).
    (_:Qa _:Qb) :neta _:D3.
    (_:D1 _:C _:Qa) :dff _:Za.
    (_:D2 _:C _:Qb) :dff _:Zb.
    (_:D3 _:C _:Qc) :dff _:Zc.
}.


(_:S) log:onNegativeSurface {
    () log:onQuerySurface {
        (() _:S) :testgcc ().
    }.
}.

(_:Cc _:S _:Nc _:C _:Cs _:N _:Ns) log:onNegativeSurface {
    () log:onQuerySurface {
        (_:Cc _:S) :testgcc _:Nc.
    }.
    _:Cc list:firstRest (_:C _:Cs).
    _:Nc list:firstRest (_:N _:Ns).
    (_:C _:S) :gcc _:N.
    (_:Cs _:N) :testgcc _:Ns.
}.

(_:Q) log:onQuerySurface {
    ((1 1 1 1 1 1 1 1 1) (0 0 0)) :testgcc _:Q.
}.
