このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1361082416/887
#  [1] 授業単元:暇つぶし 
#  [2] 問題文(含コード&リンク): 
#  2次元平面上における2線分の交点座標を求めよ 
#   
#  8つの整数 x1, y1, x2, y2, x3, y3, x4, y4 が与えられる 
#  線分ABを 点A(x1,y1) と 点B(x2,y2) とを繋ぐ線分とする 
#  線分CDを 点C(x3,y3) と 点D(x4,y4) とを繋ぐ線分とする 
#   
#  線分AB と 線分CD との交点座標を小数点表記で出力せよ(誤差は1e-20未満とする) 
#  交点が無い場合には「交点無し」と出力せよ 
#   
#  線分の端点での交差も認めることとし 
#  与えられる整数は -10000以上10000以下とする 
#   
#  

'2次元平面上における2線分の交点座標を求めよ 
 
8つの整数 x1, y1, x2, y2, x3, y3, x4, y4 が与えられる 
線分ABを 点A(x1,y1) と 点B(x2,y2) とを繋ぐ線分とする 
線分CDを 点C(x3,y3) と 点D(x4,y4) とを繋ぐ線分とする 
 
線分AB と 線分CD との交点座標を小数点表記で出力せよ(誤差は1e-20未満とする) 
交点が無い場合には「交点無し」と出力せよ 
 
線分の端点での交差も認めることとし 
与えられる整数は -10000以上10000以下とする'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :-
        '2次元平面上における2線分の交点座標を求めよ'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y).

'2次元平面上における2線分の交点座標を求めよ'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :-
        'x1,y1,x2,y2を通る線分の方程式の係数'(_x1,_y1,_x2,_y2,A1,B1),
        'x3,y3,x4,y4を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A2,B2),
        二元一次連立方程式を解く(A1,B1,A2,B2,_x,_y),
        'x,yは二つの線分上にある'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y).

'x1,y1,x2,y2を通る線分の方程式の係数'(_x1,_y1,_x2,_y2,A,B) :-
        係数Aの算出(_x,_y1,_x2,_y2,_m_2,A),
        係数Bの算出(_n_1,_y1,_m_2,B).

係数Aの算出(_x,_y1,_x2,_y2,_m_2,A) :-
        _m_1 is _y2 - _y1,
        _n_1 is _x2 - _x1,
        A_1 = (_m_1 / _n_1),
        _m_2 is _y1 * _x1 - _y2 * _x1,
        約分(A_1,A).

係数Bの算出(_n_1,_y1,_m_2,B) :-
        _n_2 is _n_1 * _y1 + _m_2,
        B_1 = (_n_2 / _n_1),
        約分(B_1,B).

'x3,y3,x4,y4を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A,B) :-
        'x1,y1,x2,y2を通る線分の方程式の係数'(_x3,_y3,_x4,_y4,A,B).

二元一次連立方程式を解く(A1,B1,A2,B2,_x,_y) :-
        既約ガウス行列に変形([[A1,-1,-B1],[A2,-1,-B2]],[[_,_,_x],[_,_,_y]]),!.

'x,yは二つの線分上にある'(_x1,_y1,_x2,_y2,_x3,_y3,_x4,_y4,_x,_y) :-
        'x,yは直線上にある'(_x1,_y1,_x2,_y2,_x,_y),
        'x,yは直線上にある'(_x3,_y3,_x4,_y4,_x,_y).

'x,yは直線上にある'(_x1,_y1,_x2,_y2,_x,_y) :-
        'xは範囲にある'(_x1,_x2,_x),
        'xは範囲にある'(_x3,_x4,_x),
        'yは範囲にある'(_y1,_y2,_y),
        'yは範囲にある'(_y3,_y4,_y),!.

'xは範囲にある'(_x1,_x2,_x) :-
        x2がx1と等しいか大きい場合(_x1,_x2,_x).
'xは範囲にある'(_x1,_x2,_x) :-
        x2がx1より小さい場合(_x1,_x2,_x).

'yは範囲にある'(_y1,_y2,_y) :-
        y2がy1と等しいか大きい場合(_y1,_y2,_y).
'yは範囲にある'(_y1,_y2,_y) :-
        y2がy1より小さい場合(_y1,_y2,_y).

x2がx1と等しいか大きい場合(_x1,_x2,_x) :-
        _x1 =< _x2,
        _x >= _x2,
        _x =< _x1.

x2がx1より小さい場合(_x1,_x2,_x) :-
        _x1 > _x2,
        _x >= _x1,
        _x =< _x2.

y2がy1と等しいか大きい場合(_y1,_y2,_y) :-
        _y1 =< _y2,
        _y >= _y2,
        _y =< _y1.

y2がy1より小さい場合(_y1,_y2,_y) :-
        _y1 > _y2,
        _y >= _y1,
        _y =< _y2.

約分(B / A,X) :-
        最大公約数(B,A,C),
        _分子 is B // C,
        _分母 is A // C,
        約分の二(_分子,_分母,X),!.

約分の二(_分子,1,_分子) :- !.
約分の二(_分子,1.0,_分子) :- !.
約分の二(_分子,_分母,_分子 / _分母).

最大公約数(M,N,X) :-
        最大公約数をユークリッドの互除法で求める(M,N,X),!.

最大公約数をユークリッドの互除法で求める(M,N,N) :-
        0 is M mod N,!.
最大公約数をユークリッドの互除法で求める(M,N,X) :-
        Mod is M mod N,
        最大公約数をユークリッドの互除法で求める(N,Mod,X).