# Lee routing for VLSI circuits

@prefix math: <http://www.w3.org/2000/10/swap/math#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
@prefix e: <http://eulersharp.sourceforge.net/2003/03swap/log-rules#>.
@prefix : <https://eyereasoner.github.io/eye/reasoning#>.

{(?Source ?Destination ?Obstacles) :route ?Path} <= {
    (?Destination ((?Source) ()) ?Obstacles) :waves ?Waves.
    (?Source ?Destination ?Waves) :path ?P.
    ?P e:reverse ?Path.
}.

{(?B ?Waves1 ?Obstacles) :waves ?Waves} <= {
    ?Waves1 e:firstRest (?Wave ?Waves).
    ?Wave list:member ?B.
    true log:callWithCut true.
}.
{(?B ?Waves1 ?Obstacles) :waves ?Waves} <= {
    ?Waves1 e:firstRest (?Wave ?Waves2).
    ?Waves2 e:firstRest (?LastWave ?LastWaves).
    ?SCOPE e:findall (?X {(?X ?Wave ?LastWave) :admissible ?Obstacles} ?List).
    ?List e:sort ?NextWave.
    ?Waves3 e:firstRest (?NextWave ?Waves1).
    (?B ?Waves3 ?Obstacles) :waves ?Waves.
}.

{(?X ?Wave ?LastWave) :admissible ?Obstacles} <= {
    (?X ?Wave) :adjacent ?Obstacles.
    ?SCOPE e:fail {?LastWave list:member ?X}.
    ?SCOPE e:fail {?Wave list:member ?X}.
}.

{(?X ?Wave) :adjacent ?Obstacles} <= {
    ?Wave list:member ?X1.
    ?X1 :neighbor ?X.
    ?SCOPE e:fail {?X :obstructed ?Obstacles}.
}.

{(?X1 ?Y) :neighbor (?X2 ?Y)} <= {
    ?X1 :next_to ?X2.
}.
{(?X ?Y1) :neighbor (?X ?Y2)} <= {
    ?Y1 :next_to ?Y2.
}.

{?X :next_to ?X1} <= {
    (?X 1) math:sum ?X1.
}.
{?X :next_to ?X1} <= {
    ?X math:greaterThan 0.
    (?X -1) math:sum ?X1.
}.

{?Point :obstructed ?Obstacles} <= {
    ?Obstacles list:member ?Obstacle.
    ?Point :obstructs ?Obstacle.
}.

{(?X ?Y) :obstructs ((?X ?Y1) (?X2 ?Y2))} <= {
    ?Y1 math:notGreaterThan ?Y.
    ?Y math:notGreaterThan ?Y2.
}.
{(?X ?Y) :obstructs ((?X1 ?Y1) (?X ?Y2))} <= {
    ?Y1 math:notGreaterThan ?Y.
    ?Y math:notGreaterThan ?Y2.
}.
{(?X ?Y) :obstructs ((?X1 ?Y) (?X2 ?Y2))} <= {
    ?X1 math:notGreaterThan ?X.
    ?X math:notGreaterThan ?X2.
}.
{(?X ?Y) :obstructs ((?X1 ?Y1) (?X2 ?Y))} <= {
    ?X1 math:notGreaterThan ?X.
    ?X math:notGreaterThan ?X2.
}.

{(?A ?A ?B) :path (?A)} <= {
    true log:callWithCut true.
}.
{(?A ?B ?Waves1) :path ?Path1} <= {
    ?Waves1 e:firstRest (?Wave ?Waves).
    ?Path1 e:firstRest (?B ?Path).
    ?Wave list:member ?B1.
    ?B :neighbor ?B1.
    true log:callWithCut true.
    (?A ?B1 ?Waves) :path ?Path.
}.
