27
28:-module(did_you_know,
29 [ did_you_know_script//1,
30 did_you_know//0
31 ]). 32
38
39:- use_module(library(http/html_write)). 40:- use_module(library(http/http_dispatch)). 41:- use_module(library(random)). 42:- use_module(library(debug)). 43:- use_module(news). 44:- use_module(holidays). 45:- use_module(page). 46:- use_module(library(http/js_write)). 47
48:- http_handler(root(dyk), did_you_know, []). 49
53
54did_you_know(_Request) :-
55 disable_client_cache,
56 reply_html_page(plain,
57 title('SWI-Prolog Did You Know'),
58 \did_you_know).
59
60disable_client_cache :-
61 format('Cache-Control: private, no-store\r\n').
62
66
67did_you_know_script(Id) -->
68 html('Did you know ... '),
69 { http_link_to_id(did_you_know, [], HREF) },
70 js_script({|javascript(Id, HREF)||
71 $(function() {
72 $.ajax({ url: HREF,
73 success: function(data) {
74 console.log(data);
75 $("#"+Id).html(data);
76 }
77 });
78 });
79 |}).
80
81
85
86did_you_know -->
87 { maybe(0.2) },
88 !,
89 html([ span(class('dyk-sponsor'), 'We need you to '),
90 \github_actions([sponsor]),
91 span(class('dyk-sponsor'), ' to keep SWI-Prolog sustainable')
92 ]).
93did_you_know -->
94 { maybe(0.5) },
95 random_news, !.
96did_you_know -->
97 { todays_holiday(april_fools_day),
98 maybe(0.1)
99 },
100 random_silly_hint.
101did_you_know -->
102 random_hint.
103
104random_silly_hint -->
105 { predicate_property(afdyk(_,_), number_of_clauses(N)),
106 ( debugging(dyk(Id)),
107 integer(Id)
108 -> true
109 ; random_between(1, N, Id)
110 ),
111 afdyk(Id, Saying)
112 },
113 say_af_saying(Saying).
114
115say_af_saying(Text-Link) -->
116 { link(Link, HREF) },
117 html([ span(class(lbl), 'Did you know?'),
118 ' ',
119 span(id(dyknow), a(href(HREF), Text))
120 ]).
121say_af_saying(news(Text-Link)) -->
122 { link(Link, HREF) },
123 html([ span(class(lbl), 'News:'),
124 ' ',
125 span(id(dyknow), a(href(HREF), Text))
126 ]).
127say_af_saying(news(Text)) -->
128 html([ span(class(lbl), 'News:'),
129 ' ',
130 span(id(dyknow), Text)
131 ]).
132say_af_saying(Text) -->
133 html([ span(class(lbl), 'Did you know?'),
134 ' ',
135 span(id(dyknow), Text)
136 ]).
137
138random_hint -->
139 { predicate_property(dyk(_,_), number_of_clauses(N)),
140 ( debugging(dyk(Id)),
141 integer(Id)
142 -> true
143 ; random_between(1, N, Id)
144 ),
145 dyk(Id, Saying),
146 ( Saying = (Text-Link)
147 -> link(Link, HREF),
148 Info = a(href(HREF), Text)
149 ; Info = Saying
150 )
151 },
152 html([ span(class(lbl), 'Did you know?'),
153 ' ',
154 span(id(dyknow), Info)
155 ]).
156
157link(section(Id), HREF) :- !,
158 http_link_to_id(pldoc_man, [section=Id], HREF).
159link(package(Name), HREF) :- !,
160 file_name_extension(Name, html, File),
161 http_link_to_id(pldoc_package, path_postfix(File), HREF).
162link(pack(Name), HREF) :- !,
163 http_link_to_id(pack_list, [p(Name)], HREF).
164link(HREF, HREF).
165
166
175:- multifile term_expansion/2. 176
177:- nb_setval(dyk_id, 1). 178term_expansion(dyk(Saying), dyk(Id, Saying)) :-
179 nb_getval(dyk_id, Id),
180 Id2 is Id+1,
181 nb_setval(dyk_id, Id2).
182
183dyk('SWI-Prolog is 28 years old').
184dyk(['the ', b('Profiler'), ' can speed up your code']-section('profiling-predicates')).
185dyk('You can hot-swap code').
186dyk('SWI-Prolog uses logical update view'-section('update')).
187dyk('M-/ does autocomplete in pceEmacs').
188dyk('C-c C-c CamelCasesWords in pceEmacs').
189dyk('C-c C-- underscores_words_in_pce_emacs').
190dyk('C-+ and C-- changes font size in pceEmacs').
191dyk('About the nifty drawing program pceDraw').
192dyk('Special quasiquote syntax for html and javascript'-section('quasiquotations')).
193dyk('Advice for choosing 32/64 bits'-section('64bits')).
194dyk('You can configure your environment'-section('initfile')).
195dyk(['SWI-Prolog supports the ', b('Snowball'), ' stemmer']-section('snowball')).
196dyk(['SWI-Prolog supports ', b(tabling), ' (SLG resolution)']-section('tabling')).
197dyk('SWI-Prolog has an RDF Semantic Web Server'-'http://cliopatria.swi-prolog.org/home').
198dyk('You can interface C++ to SWI-Prolog'-package('pl2cpp')).
199dyk('SWI-Prolog can work with tar archives'-package('archive')).
200dyk('This website is written entirely in SWI-Prolog'-package('http')).
201dyk(['about the full featured ', b('web framework')]-package('http')).
202dyk(['SWI-Prolog can act as an ', b('http client')]-section('http-clients')).
203dyk('SWI-Prolog supports PDT, the Prolog Development Tools'-package('pdt')).
204dyk('You can get Javadoc style documentation automatically'-package('pldoc')).
205dyk(['SWI-Prolog has a ', b('unit test framework')]-package('plunit')).
206dyk(['SWI-Prolog has a ', b('Natural Language Processing (NLP)'), ' library']-package('nlp')).
207dyk(['SWI-Prolog supports ', b('Google Protocol Buffers')]-package('protobufs')).
208dyk('SWI-Prolog talks to R'-package('R')).
209dyk(['SWI-Prolog has ', b('powerful Semantic Web tools')]-package('semweb')).
210dyk(['SWI-Prolog can ', b('parse SGML/XML')]-package('sgml')).
211dyk(['SWI-Prolog has extensive ', b('GIS Support')]-package('space')).
212dyk(['SWI-Prolog has support for ', b('large, static tables')]-package('table')).
213dyk(['SWI-Prolog supports ', b('TIPC')]-package('tipc')).
214dyk(['You can read/write ', b('.zip'), ' files']-package('zlib')).
215dyk(['SWI-Prolog can talk to Java,C,C++,Python,and C#']-'/contrib/').
216dyk(['You can control ', b('MIDI'), ' on Mac with SWI-Prolog']-'/contrib/SamerAbdallah/index.html').
217dyk(['SWI-Prolog has ', b('an OpenGL Interface')]-'/contrib/OpenGL.html').
218dyk(['SWI-Prolog is highly ', b('cross platform')]).
219dyk('SWI-Prolog has multiple high quality random number generators'-'/contrib/SamerAbdallah/index.html').
220dyk('The SWI-Prolog manual is available in printed form'-
221 'http://books.google.nl/books/about/SWI_Prolog_Reference_Manual_6_2_2.html?id=q6R3Q3B-VC4C&redir_esc=y').
222dyk(['ETALIS ', b('Event Processing'), ' runs on SWI-Prolog']-'http://code.google.com/p/etalis/').
223dyk('This website\'s code is available'-'https://github.com/SWI-Prolog/plweb').
224dyk(['SWI-Prolog can talk to ', b('Matlab')]-'/contrib/SamerAbdallah/index.html').
225dyk(['SWI-Prolog has an active ', b('mailing list')]-'/Mailinglist.html').
226dyk(['Jan loves it when you ', b('Report Bugs')]-'https://github.com/SWI-Prolog/issues/issues').
227dyk(['You can get ', span(class=colored, 'COLORED'), ' text on the command line']-'/FAQ/ColorConsole.html').
228dyk(['SWI-Prolog has a ', b('Nifty IDE')]-'/IDE.html').
229dyk(['SWI-Prolog has a ', b('Graphic Debugger')]-'/gtrace.html').
230dyk(['Try C-c C-n in pceEmacs']-'/navigator.html').
231dyk('Try gxref. from the top level with a large project open'-'/gxref.html').
232dyk('XPCE supports a sophisticated styled text engine').
233dyk('Your proprietary application can use SWI-Prolog'-'/license.html').
234dyk(['SWI-Prolog has an interface to FANN, a foss ', b('Neural Net'), ' library']-'http://leenissen.dk/fann/wp/').
235dyk('SWI-Prolog has lots of useful Packages'-'/pack/list').
236dyk(['SWI-Prolog can ', b('track open source licenses')]-section(softlicense)).
237dyk(['SWI-Prolog has a pack to access ', b('Pubmed Data')]-pack(pubmed)).
238dyk(['SWI-Prolog has ', b('Multi-Thread support')]-section(threads)).
239dyk(['SWI-Prolog provides ', b('general DCG primitives')]-'/pldoc/doc/swi/library/dcg/basics.pl').
240dyk('SWI-Prolog can handle Unix signals'-section(signal)).
241dyk('SWI-Prolog can lazily parse a file'-section(pureinput)).
242dyk('You can add menus to the swipl-win.exe console in windows'-section(plwin)).
243dyk(['SWI-Prolog has a ', b('Profiler')]-section(profile)).
244dyk('SWI-Prolog supports DDE on Windows'-section('DDE')).
245dyk(['You can create ', b('stand alone exe files'), ' from SWI-Prolog code']-section(runtime)).
246dyk('SWI-Prolog supports arbitrarily large integers').
248dyk(['There\'s an API to interact with', b('Amazon')]-pack(amazon_api)).
249dyk('Nifty call graphs'-pack(callgraph)).
250dyk('condition is an alternative to exceptions'-pack(condition)).
251dyk('You can train markov chains with BIMS'-pack(bims)).
252dyk('blog_core is a nifty CMS for SWI-Prolog'-pack(blog_core)).
253dyk('anything in single quotes is an atom').
254dyk('Logtalk is now a pack'-pack(logtalk)).
255dyk('SWI-Prolog has probabilistic logic'-pack(cplint)).
256dyk(['DCG help at lib ',
257 a(href='/pldoc/doc/swi/library/dcg/basics.pl', 'dcg/basics'),
258 ' & packs dcg_util & dcg_utils']).
259dyk('automatic UML->Prolog translation'-pack(dia)).
260dyk('docstore is a document oriented DB in SWI-Prolog'-pack(docstore)).
261dyk('you can deploy to dotcloud'-pack(dotcloud)).
262dyk('CQL makes dealing with SQL easier'-section('/packages/cql.html')).
263dyk('you can turn ugraphs into graphml'-pack(graphml)).
264dyk('you can turn terms into graphviz (.dot) files'-pack(gvterm)).
265dyk('about nifty JoCaml style multithreading'-pack(jolog)).
266dyk('the first Prolog interpreter was in Algol-W by Philippe Roussel (1972)').
267dyk('julian pack offers match based dates'-pack(julian)).
268dyk('eliminate helper predicates with pack lambda'-pack(lambda)).
269dyk('you can parse markdown').
270dyk('don\'t use format to print errors'-section(debug)).
271dyk('there\'s a simplex library'-section(simplex)).
272dyk('use mavis for type checking'-pack(mavis)).
273dyk('you can read ODF spreadsheets'-pack(odf_sheet)).
274dyk('how to submit a patch'-'/howto/SubmitPatch.html').
275dyk('add language:prolog in github search').
276dyk('there is an official Docker library for SWI-Prolog'-'/Docker.html').
277dyk('there is a Docker image SWISH'-'/Docker.html').
278dyk('SWI-Prolog runs on Android Termux'-'/build/Termux.html').
279
291
292term_expansion(afdyk(Saying), afdyk(Id, Saying)) :-
293 ( predicate_property(afdyk(_,_), number_of_clauses(N))
294 -> Id is N+1
295 ; Id = 1
296 ).
297
298afdyk('SWI-Prolog complies with ISO JTC1/SC22/WG4'-'http://cobolstandard.info/wg4/wg4.html').
299afdyk('C-c C-q automatically corrects syntax errors'-'/AprilFools.html').
300afdyk('SWI-Prolog defaults to EBCDIC'-'/AprilFools.html').
301afdyk(news('SWI-Prolog is now available on 9-track tape'-'/AprilFools.html')).
302afdyk('pack_install(agi) installs Skynet'-'/AprilFools.html').
303afdyk(['SWI-Prolog powers ', a(href='http://java.com' , 'this popular site')]).
304afdyk('http_get is (?, ?, +)').
305afdyk(news('A SWI-Prolog program beat the world champion in box hockey'-'/AprilFools.html')).
306afdyk('8cD'-'https://github.com/Anniepoo/prolog-examples/blob/master/emoticons.pl').
307afdyk(news('Bill Joy admits he\'s wrong, urges Prolog'-'/AprilFools.html')).
308afdyk(['Prolog actually ', b('IS'), ' good for torturing undergrads']-'/AprilFools.html').
309afdyk(news('Colmerauer admits Prolog isn\'t logical at all'-'/AprilFools.html')).
310afdyk('about pack(antigravity)'-'/AprilFools.html').
311afdyk('SWI-Prolog 7.1.29 requires OSGi and qPID'-'/AprilFools.html').
312afdyk('this website powered by windmills'-'/dogfood.html').
313afdyk('Nou breekt mijn klomp. Prolog is beter!'-'/AprilFools.html').
314afdyk('about pack(klomp)'-'/AprilFools.html').
315afdyk('about pack(cheese)'-'/AprilFools.html').
316afdyk('about pack(chocolate)'-'/AprilFools.html').
317afdyk('about pack(evil)'-pack(evil)).
318afdyk('Use Appendix B for clear code'-section(hack)).
319afdyk('Early Prologs ended clauses with AMEN'-
320 'http://web.archive.org/web/20070703003934/www.lim.univ-mrs.fr/~colmer/ArchivesPublications/HistoireProlog/19november92.pdf').
321afdyk('test'-pack(abdcsd))