1:- module(ap_cli, [main/1, start/0]). 2 3:- use_module(library(lists)). 4:- use_module(library(readutil)). 5:- use_module(ap_ui). 6:- use_module(ap_defaults). 7:- use_module(ap_model). 8:- use_module(ap_report). 9:- use_module(ap_simulation). 10:- use_module(ap_compare). 11:- use_module(ap_io). 12:- use_module(ap_audit). 13:- use_module(ap_legal). 14:- use_module(ap_reference). 15:- use_module(ap_calibration). 16:- use_module(ap_version). 17 18main(Argv) :- 19 ( Argv = ['--help'|_] -> help 20 ; Argv = ['--version'|_] -> ap_version:version_string(V), format('~w~n', [V]) 21 ; Argv = ['simulate', File|_] -> cli_simulate_file(File) 22 ; Argv = ['evaluate', File|_] -> cli_evaluate(File) 23 ; start 24 ). 25 26start :- 27 ap_defaults:default_scenario(S), 28 menu_loop(S). 29 (Current) :- 31 ap_ui:clear_screen, 32 ap_ui:banner, 33 format('Skenario aktif: ~w~n', [Current.name]), 34 format('~n[1] Simulasi cepat (guided)~n', []), 35 format('[2] Edit semua variabel (advanced)~n', []), 36 format('[3] Jalankan skenario aktif~n', []), 37 format('[4] Simulasikan 7 hari ke depan~n', []), 38 format('[5] Bandingkan respons kebijakan~n', []), 39 format('[6] Simpan skenario~n', []), 40 format('[7] Muat skenario~n', []), 41 format('[8] Lihat audit log lokal~n', []), 42 format('[9] Metodologi / hukum / referensi~n', []), 43 format('[10] Evaluasi model dari CSV historis~n', []), 44 format('[11] Muat skenario contoh~n', []), 45 format('[12] Export hasil aktif ke JSON~n', []), 46 format('[0] Keluar~n~n', []), 47 read_choice(Choice), 48 dispatch(Choice, Current, Next, Continue), 49 ( Continue == yes -> menu_loop(Next) ; true ). 50 51read_choice(C) :- 52 format('Pilih: '), flush_output, 53 read_line_to_string(user_input, S0), normalize_space(string(S), S0), 54 ( catch(number_string(C0, S), _, fail) -> C=C0 ; C = -1 ). 55 56dispatch(1, S0, S, yes) :- !, guided(S0, S), run_and_pause(S). 57dispatch(2, S0, S, yes) :- !, advanced(S0, S), run_and_pause(S). 58dispatch(3, S, S, yes) :- !, run_and_pause(S). 59dispatch(4, S, S, yes) :- !, timeline_screen(S), ap_ui:pause. 60dispatch(5, S, S, yes) :- !, ap_compare:compare_responses(S, Rs), ap_report:print_comparison(Rs), ap_ui:pause. 61dispatch(6, S, S, yes) :- !, save_screen(S), ap_ui:pause. 62dispatch(7, S0, S, yes) :- !, load_screen(S0, S), ap_ui:pause. 63dispatch(8, S, S, yes) :- !, ap_audit:show_audit, ap_ui:pause. 64dispatch(9, S, S, yes) :- !, methodology_screen, ap_ui:pause. 65dispatch(10, S, S, yes) :- !, evaluate_screen, ap_ui:pause. 66dispatch(11, S0, S, yes) :- !, example_screen(S0, S), run_and_pause(S). 67dispatch(12, S, S, yes) :- !, export_screen(S), ap_ui:pause. 68dispatch(0, S, S, no) :- !, format('dadah. jangan lupa: kritik kebijakan ≠ kriminal. 💀~n', []). 69dispatch(_, S, S, yes) :- format('Pilihan tidak dikenal.~n', []), ap_ui:pause. 70 71run_and_pause(S) :- 72 ap_model:score(S, R), 73 ap_report:print_report(R), 74 catch(ap_audit:record_report(R), E, print_message(warning, E)), 75 ap_ui:pause. 76 77guided(S0, S) :- 78 ap_ui:prompt_string('Nama skenario', S0.name, Name), 79 scope_options(ScopeOpts), ap_ui:prompt_choice('Skala isu', ScopeOpts, 2, Scope), 80 issue_options(IssueOpts), ap_ui:prompt_choice('Jenis isu', IssueOpts, 5, Issue), 81 target_options(TargetOpts), ap_ui:prompt_choice('Target tuntutan', TargetOpts, 1, Target), 82 ap_ui:prompt_string('Sub-isu singkat', S0.subissue, Sub), 83 ap_ui:prompt_string('Provinsi', S0.province, Province), 84 ap_ui:prompt_string('Kota/lokasi umum (tanpa alamat pribadi)', S0.city, City), 85 ap_ui:prompt_number('Akumulasi keluhan', 0,100,S0.grievance,Grievance), 86 ap_ui:prompt_number('Kekuatan pemicu', 0,100,S0.trigger,Trigger), 87 ap_ui:prompt_number('Kepentingan/salience isu',0,100,S0.salience,Salience), 88 ap_ui:prompt_number('Dukungan publik pada tuntutan',0,100,S0.public_support,Support), 89 ap_ui:prompt_number('Momentum daring',0,100,S0.online,Online), 90 ap_ui:prompt_number('Responsivitas/dialog pemerintah',0,100,S0.govt_responsiveness,Resp), 91 ap_ui:prompt_number('Kualitas bukti input',0,100,S0.evidence_quality,Q), 92 put_dict(_{name:Name,scope:Scope,issue:Issue,target:Target,subissue:Sub,province:Province,city:City, 93 grievance:Grievance,trigger:Trigger,salience:Salience,public_support:Support,online:Online, 94 govt_responsiveness:Resp,evidence_quality:Q}, S0, S). 95 96advanced(S0, S) :- 97 guided(S0, G), 98 advanced_pairs([ 99 coalition-'Kekuatan koalisi', organization-'Kapasitas organisasi', 100 economic_stress-'Tekanan ekonomi', institutional_distrust-'Ketidakpercayaan institusional', 101 incident_shock-'Insiden pemicu tambahan', recent_precedent-'Preseden aksi terbaru', 102 media_attention-'Perhatian media', regional_relevance-'Relevansi lintas wilayah', 103 govt_communication-'Kualitas komunikasi pemerintah', organizer_control-'Disiplin/kontrol penyelenggara', 104 intervention_pressure-'Tekanan/intervensi terhadap aksi' 105 ], G, S1), 106 ap_ui:prompt_number('Durasi skenario (hari)',1,365,S1.duration_days,Days), 107 ap_ui:prompt_number('Populasi area (juta)',0.01,300,S1.population_millions,Pop), 108 ap_ui:prompt_number('Seed simulasi',1,2147483647,S1.seed,Seed), 109 notify_options(NOpts), ap_ui:prompt_choice('Status pemberitahuan aksi', NOpts, 3, Notified), 110 put_dict(_{duration_days:Days,population_millions:Pop,seed:Seed,notified:Notified}, S1, S). 111 112advanced_pairs([], S, S). 113advanced_pairs([Key-Label|Xs], S0, S) :- 114 get_dict(Key, S0, Default), 115 ap_ui:prompt_number(Label,0,100,Default,V), 116 put_dict(Key, S0, V, S1), 117 advanced_pairs(Xs, S1, S). 118 119scope_options(Opts) :- findall(I-V-T, (ap_defaults:scope(I,V), atom_string(V,T)), Opts). 120issue_options(Opts) :- findall(I-V-T, (ap_defaults:issue(I,V), atom_string(V,T)), Opts). 121target_options(Opts) :- findall(I-V-T, (ap_defaults:target(I,V), atom_string(V,T)), Opts). 122notify_options([1-yes-'Ya',2-no-'Tidak',3-unknown-'Tidak diketahui']). 123 124timeline_screen(S) :- 125 ap_simulation:timeline(S, 7, Reports, Events), 126 format('~nTIMELINE 7 HARI (seed deterministik ~w)~n', [S.seed]), 127 print_days(Reports, 0), 128 format('~nEvent drift:~n', []), forall(member(E, Events), format(' - ~w~n',[E])). 129 130print_days([], _). 131print_days([R|Rs], Day) :- 132 format('Hari +~w: likelihood ~w | spread ~w | escalation ~w | ~w~n', 133 [Day,R.likelihood,R.spread,R.escalation,R.predicted_state]), 134 D1 is Day+1, print_days(Rs,D1). 135 136save_screen(S) :- 137 ap_ui:prompt_string('Nama file', 'skenario', F), 138 catch((ap_io:save_scenario(F,S), format('Tersimpan.~n',[])), E, print_message(error,E)). 139 140load_screen(_S0, S) :- 141 ap_ui:prompt_string('File skenario', 'skenario.ap.pl', F), 142 catch(ap_io:load_scenario(F,S1), E, (print_message(error,E), fail)), !, S=S1. 143load_screen(S, S). 144 145 146example_screen(_S0, S) :- 147 Options = [ 148 1-'scenario_bbm.ap.pl'-'BBM / tekanan ekonomi', 149 2-'scenario_ukt.ap.pl'-'UKT / pendidikan', 150 3-'scenario_integritas.ap.pl'-'Integritas / antikorupsi' 151 ], 152 ap_ui:prompt_choice('Pilih skenario contoh', Options, 1, Base), 153 example_file(Base, File), 154 catch(ap_io:load_scenario(File, S1), E, (print_message(error,E), fail)), !, 155 S = S1. 156example_screen(S, S). 157 158example_file(Base, File) :- 159 source_file(ap_cli:start, Here), 160 file_directory_name(Here, PrologDir), 161 file_directory_name(PrologDir, PackDir), 162 directory_file_path(PackDir, examples, ExamplesDir), 163 directory_file_path(ExamplesDir, Base, File). 164 165export_screen(S) :- 166 ap_model:score(S, R), 167 ap_ui:prompt_string('Nama file JSON', 'hasil-antisipasipejabat', F), 168 catch((ap_io:export_report_json(F, R), format('Hasil diekspor ke JSON.~n', [])), 169 E, print_message(error,E)). 170 171methodology_screen :- 172 format('~nMETODOLOGI SINGKAT~n', []), 173 format('- Model v0.1 = weighted explainable heuristic, belum diklaim terkalibrasi.~n', []), 174 format('- Memisahkan likelihood, spread, escalation, pressure, confidence.~n', []), 175 format('- Turnout memakai bucket, bukan jumlah presisi.~n', []), 176 format('- Tidak ada profiling individu, daftar aktivis, rute, atau rekomendasi penindakan.~n', []), 177 ap_legal:legal_summary, 178 ap_reference:print_references. 179 180evaluate_screen :- 181 ap_ui:prompt_string('CSV historis', 'examples/historical_synthetic.csv', F), 182 cli_evaluate(F). 183 184cli_evaluate(File) :- 185 catch((ap_calibration:evaluate_csv(File,S), ap_calibration:print_evaluation(S)), E, print_message(error,E)). 186 187cli_simulate_file(File) :- 188 catch((ap_io:load_scenario(File,S), ap_model:score(S,R), ap_report:print_report(R)), E, print_message(error,E)). 189 190help :- 191 format('Antisipasi Pejabat v0.1.0.0~n', []), 192 format(' swipl antisipasipejabat # menu interaktif~n', []), 193 format(' swipl antisipasipejabat --help # bantuan~n', []), 194 format(' swipl antisipasipejabat --version # versi~n', []), 195 format(' swipl antisipasipejabat simulate FILE.ap.pl~n', []), 196 format(' swipl antisipasipejabat evaluate FILE.csv~n', [])