/**************************************************************************************/
/* File:        demo35                                                                */
/* Project:     ATSQL2 : Safely connected train stations (non-temporal)               */
/* Author:      Andreas Steiner                                                       */
/* Date:        29-09-1995                                                            */
/* Results:                                                                           */
/**************************************************************************************/

/******************/
/* train stations */
/******************/

CREATE TABLE station(name CHAR(6));

INSERT INTO station VALUES('a');
INSERT INTO station VALUES('b');
INSERT INTO station VALUES('c');
INSERT INTO station VALUES('d');


/**********************/
/* direct connections */
/**********************/

CREATE TABLE link(from_station CHAR(10), to_station CHAR(10));

INSERT INTO link VALUES('a','b');
INSERT INTO link VALUES('a','c');
INSERT INTO link VALUES('b','c');
INSERT INTO link VALUES('c','d');


/***************/
/* connections */
/***************/

CREATE TABLE connected(from_station CHAR(10), to_station CHAR(10));

INSERT INTO connected
  SELECT A1.from_station, A1.to_station
  FROM   link A1;

INSERT INTO connected
    SELECT A1.from_station, A2.to_station
    FROM   connected A1, connected A2
    WHERE  A1.to_station=A2.from_station
    EXCEPT
    SELECT * FROM connected A0;

INSERT INTO connected
    SELECT A1.from_station, A2.to_station
    FROM   connected A1, connected A2
    WHERE  A1.to_station=A2.from_station
    EXCEPT
    SELECT * FROM connected A0;

SELECT * FROM connected;

/*
 from_station to_station
 ------------ ----------
            a          b
            a          c
            b          c
            c          d
            a          d
            b          d
*/


/**************/
/* circumvent */
/**************/

CREATE TABLE circumvent(inter CHAR(10), from_station CHAR(10), to_station CHAR(10));

INSERT INTO circumvent
  SELECT A1.name, A2.from_station, A2.to_station
  FROM   station A1, link A2
  WHERE  A1.name<>A2.to_station AND A1.name<>A2.from_station;

INSERT INTO circumvent
  SELECT a1.inter, A1.from_station, A2.to_station
  FROM   circumvent A1, circumvent A2
  WHERE  A1.inter=A2.inter AND A1.to_station=A2.from_station
  EXCEPT
  SELECT * FROM circumvent A0;

INSERT INTO circumvent
  SELECT a1.inter, A1.from_station, A2.to_station
  FROM   circumvent A1, circumvent A2
  WHERE  A1.inter=A2.inter AND A1.to_station=A2.from_station
  EXCEPT
  SELECT * FROM circumvent A0;

SELECT * FROM circumvent;

/*
 inter from_station to_station
 ----- ------------ ----------
     a            b          c
     a            c          d
     b            a          c
     b            c          d
     c            a          b
     d            a          b
     d            a          c
     d            b          c
     a            b          d
     b            a          d
*/


/********/
/* safe */
/********/

CREATE TABLE safe(from_station char(10), to_station CHAR(10));

INSERT INTO safe 
  SELECT A1.from_station, A1.to_station 
  FROM   connected A1 
  WHERE  NOT EXISTS (SELECT * 
                     FROM   station A2 
                     WHERE  NOT EXISTS (SELECT * 
                                        FROM   circumvent A3 
                                        WHERE  A1.to_station = A3.to_station 
                                        AND    A1.from_station = A3.from_station 
                                        AND    A2.name = A3.inter)
                     AND    A2.name <> A1.to_station 
                     AND    A2.name <> A1.from_station) 
 EXCEPT 
  SELECT * FROM safe A0;

SELECT * FROM safe;

/*
 from_station to_station
 ------------ ----------
            a          b
            a          c
            b          c
            c          d
*/

SELECT A1.to_station
FROM   connected A1 
WHERE  NOT EXISTS (SELECT * 
                   FROM   safe A2 
                   WHERE  A1.to_station = A2.to_station
                   AND    'a' = A2.from_station) 
AND    'a' = A1.from_station;

/*
 a1.to_station
 -------------
             d
*/


DROP TABLE station;
DROP TABLE link;
DROP TABLE connected;
DROP TABLE circumvent;
DROP TABLE safe;
