Skip to content

Instantly share code, notes, and snippets.

@mh61503891
Created March 9, 2014 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mh61503891/9455125 to your computer and use it in GitHub Desktop.
Save mh61503891/9455125 to your computer and use it in GitHub Desktop.
鳥取市の鳥取地域のごみ収集ルールからCSVを生成するスクリプト
#!/opt/local/bin/swipl -q -t main -f
% 【注意:作りかけ】
% Auhtor: Masayuki Higashino
% Description: 鳥取市の鳥取地域のごみ収集ルールからCSVを生成するスクリプト。
%
% 鳥取市公式ウェブサイト:収集曜日一覧(鳥取地域)
% http://www.city.tottori.lg.jp/www/contents/1357776059978/index.html
% 週の定義
week(th(1), range(day(1), day(7))).
week(th(2), range(day(8), day(14))).
week(th(3), range(day(15), day(21))).
week(th(4), range(day(22), day(28))).
% 曜日名と番号の対応表
week(number(1), name('月')).
week(number(2), name('火')).
week(number(3), name('水')).
week(number(4), name('木')).
week(number(5), name('金')).
week(number(6), name('土')).
week(number(7), name('日')).
% 種類
type('可燃').
type('食品トレイ').
type('資源').
type('小型破砕').
type('プラスチック').
type('ペットボトル').
type('古紙類').
type('乾電池等').
% TODO もっと種類あるっぽい。
% NOTE CSVの列の順番の為に定義してる。(順番どうでも良いなら下記ルールから取り出せば良い。)
% 基本ルール
basic_rule(week(th(_), name('水')), area('相生町1丁目'), type('可燃')).
basic_rule(week(th(_), name('土')), area('相生町1丁目'), type('可燃')).
basic_rule(week(th(_), name('水')), area('相生町1丁目'), type('食品トレイ')).
basic_rule(week(th(_), name('金')), area('相生町1丁目'), type('資源')).
basic_rule(week(th(_), name('金')), area('相生町1丁目'), type('小型破砕')).
basic_rule(week(th(_), name('金')), area('相生町1丁目'), type('プラスチック')).
basic_rule(week(th(1), name('水')), area('相生町1丁目'), type('ペットボトル')).
basic_rule(week(th(3), name('水')), area('相生町1丁目'), type('ペットボトル')).
basic_rule(week(th(4), name('水')), area('相生町1丁目'), type('古紙類')).
% TODO 他の地域とかもスクレイピングして自動生成する。とりあえず手入力でこんだけ。
% 特別ルール
special_rule(remove(date(2014, 1, 1), type('可燃'))).
special_rule(change(src(date(2014, 1, 1)), dst(date(2014, 1, 8)), type('古紙類'))).
special_rule(change(src(date(2014, 1, 1)), dst(date(2014, 1, 8)), type('ペットボトル'))).
special_rule(remove(date(2014, 1, 1), type('プラスチック'))).
special_rule(remove(date(2014, 1, 1), type('食品トレイ'))).
special_rule(remove(date(2014, 1, 1), type('資源'))).
special_rule(remove(date(2014, 1, 1), type('小型破砕'))).
% TODO これも。
% こっからプログラム本体('ω')/
% TODO これ鳥取地区の特別ルールなん?
% TODO なんか警告がでるので述語名を変更したい。
week(th(N), day(DAY)) :-
week(th(N), range(day(SRC_DAY), day(DST_DAY))),
between(SRC_DAY, DST_DAY, DAY).
% TODO 他の地区対応
check_basic_rule(AREA, TYPE, date(Y, M, D)) :-
basic_rule(week(th(WEEK_TH), name(WEEK_NAME)), AREA, TYPE),
week(number(WEEK_NUMBER), name(WEEK_NAME)),
week(th(WEEK_TH), day(D)),
day_of_the_week(date(Y, M, D), WEEK_NUMBER).
check_special_rule(AREA, TYPE, date(Y, M, D)) :-
check_basic_rule(AREA, TYPE, date(Y, M, D)),
not(special_rule(remove(date(Y, M, D), TYPE))),
not(special_rule(change(src(date(Y, M, D)), dst(_), TYPE))).
check_special_rule(AREA, TYPE, date(Y, M, D)) :-
special_rule(change(src(date(SY, SM, SD)), dst(date(Y, M, D)), TYPE)),
check_basic_rule(AREA, TYPE, date(SY, SM, SD)).
% TODO 他の地区対応
check_rule(AREA, type('乾電池等'), date(Y, M, D)) :-
M rem 2 =:= 0,
findall(D0, check_special_rule(AREA, type('小型破砕'), date(Y, M, D0)), L),
min_member(MIN_D, L),
D =:= MIN_D.
check_rule(AREA, TYPE, date(Y, M, D)) :-
check_special_rule(AREA, TYPE, date(Y, M, D)).
% NOTE 基本ロジックは実質22行くらい。
% 日付ぐるぐるしながらごみの種類ごとにぐるぐるする('ω')/
% TODO このへんリファクタリングせよ。
:- dynamic main/1.
main(STAMP) :-
stamp_date_time(STAMP, DATE, 'UTC'),
DATE =.. [date, Y, M, D |_],
findall(CELL, (
type(TYPE), (
check_rule(area('相生町1丁目'), type(TYPE), date(Y, M, D))
-> CELL = true ; CELL = fase
)), CELLS),
format_time(atom(FORMATED_DATE), '%Y-%m-%d', STAMP),
day_of_the_week(date(Y, M, D), WEEK_NUMBER),
week(number(WEEK_NUMBER), name(WEEK_NAME)),
ROW =.. [row,FORMATED_DATE,WEEK_NAME|CELLS],
current_output(OUTPUT),
csv_write_stream(OUTPUT, [ROW], []),
NEXT_STAMP is STAMP + 86400,
main(NEXT_STAMP).
main :-
date_time_stamp(date(2013, 4, 1, 0, 0, 0, 0, 'UTC', false), A_STAMP),
date_time_stamp(date(2014, 4, 1, 0, 0, 0, 0, 'UTC', false), B_STAMP),
asserta(main(B_STAMP)), % 番兵
% TODO: リファクタリング
current_output(OUTPUT),
findall(TYPE, type(TYPE), TYPES),
ROW =.. [row, '日付', '曜日'|TYPES],
csv_write_stream(OUTPUT, [ROW], []),
%
main(A_STAMP).
@mh61503891
Copy link
Author

↓みたいなCSVファイルが出力されます。
日付,曜日,可燃,食品トレイ,資源,小型破砕,プラスチック,ペットボトル,古紙類,乾電池等
2013-04-01,月,fase,fase,fase,fase,fase,fase,fase,fase
2013-04-02,火,fase,fase,fase,fase,fase,fase,fase,fase
2013-04-03,水,true,true,fase,fase,fase,true,fase,fase
(以下略)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment