Account Share


Thread by @AnnieTheObscure: "ok, one retweet, one tip/fact comes with a very nifty IDE. start swipl ?- edit. You're in pceEmacs, an emacs cl […]" #prolog #SWIProlog #RDF

, 195 tweets, 41 min read
ok, one retweet, one #prolog tip/fact
#SWIProlog comes with a very nifty IDE. start swipl
?- edit. You're in pceEmacs, an emacs clone running in your vm.
C-c C-n to get a project navigator, menus to get thread monitors, debug message window.
#Prolog is a 'closed world' system. If Prolog can't prove it, it's false.
OWL, reasoning for the semantic web, is open world, and assumes there might be more triples it doesn't know.
Closed reasoning is more powerful, but is, well, "closed minded".
You can insert arbitrary transformations in code during loading, via goal_expansion/2 and term_expansion/2
#SWIProlog comes 'batteries included' - Things like the package manager and IDE are already in the base install.
#SWIProlog has a pack system. The central pack repository has over 200 entries.
Instead of thinking of #prolog as a typeless language, you can treat it as a language where the type system is 'bolted on' later. The popular mavis pack provides dynamic type checking.
The julian pack is awesome. You can describe traits of the date/time you're thinking about and it will bind variables to other traits, backtracking.
#SWIProlog is acquiring a powerful suite of cryptographic tools , various PK algos, SSL, OpenID
#SWIProlog has some of the most mature support for #RDF / semantic web of any language
#SWIProlog 7.0 changed double quote literals to compile to strings instead of codes lists, and added dicts (map structures) and distfix operators
#SWIProlog has awesome remote engine invocation via Pengines
#prolog is taught terribly. Writing 'real' Prolog code is not a mind bending puzzle. What is taught in PL classes is crazy tricks.
#prolog's module system can be used for lots of things besides encapsulating predicate namespaces
beginners often look for 'return'. Think of predicates as void, with var parameters you can set
when building up facts in #prolog, start with an understandable, ez use representation. If you need efficiency, you can use term expansion
#SWIProlog and most other mature #prolog s index on the functor and first argument at least.
Let the indexer help you, use facts instead of complex data structures
try #prolog online
Works like Jupyter notebooks too, online (ez to self host)
great way to make dashboards
once beyond "family tree" doing some web programming makes #prolog feel real - my tutorial:…
invoke graphic debugger with tspy or gtrace.
step in, over,over,over,.. fudge, too far
no problem, hit r and requery ... speeds up debug a zillion times
learn to use debug/3 and the filtering debug message window.
pceDraw - little arc and node drawing tool comes with. Use 'prototype' functionality to make domain specific drawing tools. attaching back end prolog is easy
think of nondeterminism as 'every nondet carries it's associated control structure with it'.
avoid the -> operator as a beginner.
##prolog on IRC is an awesome resource. Often takes 15 minutes for someone to notice you
bare #prolog gives you 'I know, I don't know'. Constraint programming expands that to 'I know some things about the answer, but not the whole answer'. Probablistic logic prog gives you 'I know the answer as a statistical distribution'
logic programming makes immutability not feel arbitrary. Real life reasning is monotonic
When using delimited continuations watch their size, especially if you hold them instead of immediately calling
quasiquotes are a nightmare to debug. debug compile ime transforms in a runtime test harness, and only then install in QQ or term_expansion.
#prolog doesn't evaluate arguments. This is a fundamental WTF for beginners
I spend significantly less time doing sysadmin chores and more doing business logic code in #SWIProlog than in other langs. Batteries included is as important as being a logic language.
use check_installation. to see if your #SWIProlog install is all correct.
pldoc, the literate programming tool, is much better than oxygen or javadoc.
buttons on right side to bring up code in browser or in editor
edit(foo). will move editor to foo, even if ambiguous
edit('foo/bar') will take you to the handler for the URI /foo/bar
abstract file and URI paths are awesome. most places you can give a file patch you can give eg library(foo) and find in any path registered as a lirary
eliminates directory structure nightmares.
if abstract file path magic is being your enemy today, turn on verbose_file_path flag and find out what abspats are searched
the settings library is useful
don't put writelns in libraries for exceptions! throw a semantic exception or use print_message. So the library user can control how errors are presented highr up…
I know almost no formal logic - I had a logic course in undergrad, and have learned a few things. You don't need to be a mathematician to write #prolog
Web designers whose intro to computing was CSS and HTML often have notably less problem learning #prolog than pro programmers
Jon Nichol taught grade school children #prolog in the 70's to help them learn reasoning skills. Not as CS, but as a teaching tool for other subjects!
I do less front end design in prolog because there's less 'set in concrete' feel than in other languages
the lack of contol structures makes actually introspecting clause bodies practical. CL fn bodies are opaque
projects considering #prolog worry about hiring enough prolog programmers. There are many extremely talented programmers who would love to be coding #prolog but can't find a gig
Paul Graham's secret ingredient wasn't Lisp, it was Lisp programmers. If you hire 4 #prolog today you can get 2 #prolog distro lead maintainers, 2 core swipl committers, + a dozen amazing engineers. DM me.
#SWIProlog tries hard to support commercial users. Licensing is inoffensive, and "breaking my com'l app" bugs get high priority.
You probably don't need to do a web service wrapper around your prolog, the REST support is excellent.
If you do need low latency comms across language barrier, Java and C are easy.
if you find yourself with an unwanted choice point wrap the predicate with a helper that discards it or rewrite it to eliminate, don't force caller to handle it
after writing and debugging, revisit code to ask if it's steadfast or needs to be, and if making it multimodal is a good thing
use the pattern
head :-

cut as earky as possible
I find it hard to name things declaratively. Go ahead and write with procedural names, then change them later. Then look at the code in light of the new name
names should match argument order.
parent(A,B) <-- is A the child or the parent?
parent_of(A,B) <-- clearer, but emphasizes one role
parent_child(A,B) <-- best, makes it clear A is parent, B child
_ underscore, each is a unique variable allowed to be singleton
_X actually a normal variable, but allowed to be singleton
foo(_X, _X). succeeds when its args unify serves over 350GB/month and runs on a distributed set of servers with a CDN. Somebody's using it!
Open a large project in SWIProlog. query gxref to get the cross referencer. Drag the . entry from left pane into the right pane, and ta-da, cross reference diagram for your program.
right menu info in pceEmacs shows all usages of a predicate.
Prolog supports memoization, called 'tabling' in the #prolog world.
Pengines lets you submit a query on a remote server.
any sequence of 'special' characters is an atom. You can define operators with op/3, so if you wish there was a ===> operator, make one.
query char_type(X, prolog_symbol).
to see all the chars that work this way
You can package up #SWIProlog code as an executable and not install #SWIProlog on end user machine.…
If you REALLY want to make confusing #prolog code, mix delimited continuations with examining the stack.
See prolog_current_frame/1 and reset/3
'(((('('((((') is valid prolog 🤯😱
Just because you CAN do something in #prolog isn't a reason to do so.
If languages were tools, #Prolog would be the giant saw at the lumber mill.
The #prolog way is to give you enough power to not be straining the tool. It's an opposite endpoint from Pascal. #prolog trusts programmers. Not always wisely.
67 The interactor (the ?- prompt) is NOT a 'repl'. You are entering GOALS atop the stack to be proved, not code.
68 Use atoms for constant strings, not strings or code strings. Atoms are interned - their characters stored once, reducing memory and compare time.
69 directives are arbitrary prolog code
:- writeln(howdy).
prints howdy when the compile reaches this point
70 My cat is named _
71 Nobody actually is interested in #prolog - but this thread has 10K impressions
72 swivm on linux is wonderful. Makes switching versions of SWI-Prolog easier. Even if you only have one install, it's still easiest way to do. Install the dependencies from…
then swivm is just a clone of
73 Many library predicates take 'text' and will convert whatever they're given
74 library(options) takes (typically last) argument as a named vararg list of option terms. open('', read, Stream, [mode(binary)])
Many things that do IO pass unrecognized options to the underlying IO pred...
74b this is a saner version of Java's FooReader(BarReader(.... 280 chars ... )) antipattern, and awesome for many other decorator type patterns, or even just infrequently used options
75 Prolog's not hung, it's waiting for you to type ; or . to continue
76 - 40% of all New Zealand stock trades clear through a #prolog system
virtually all aircraft gate assignments are done by a #prolog system
77 - operators are just syntactic sugar.
foo(3 + C) is identical to foo('+'(3,C)) and probably not what you want
unless foo expects an expression as an argument.
78 library(clpfd) lets you decorate variables with constraints. "I don't know what X is, but it must be less than Y" X #< Y
So if you try Y=3 and later try X = 5 as a solution it'll fail (😋good thing!)...
78b now, weird part, if you try X=5 and then later try Y= 3 it'll fail too. 😍
79 Avoid the old Edinborough tell/told style of redirecting to file
80 Prolog has exceptions. Use them in the same places you'd use exceptions in an imperative language. If you're new to Prolog, the idea that it has failure AND exceptions can be baffling....
80b failure means 'this branch of solution tree didn't yield a solution'
an exception means WTF?
81 These all invoke the pldoc structured documentation tool, which runs at consult time. So they can be baffling if you invoke accidentally
/** ... */
%! something
%% something
82 In the late 80's Japan tried to create intelligent computers and automated manufacture (today 3D printing) tech in 5th Generation Computing project. Their language was #Prolog.
83 Use multifile/1 directive to define hooks in your program. Hooks eliminate a lot of lambda patterns.
84 It's not at all uncommon for #prolog modules to export nothing, just register behaviors. Web dev does this with http_handler/3
85 Describe your world, which might involve describing a recipe (imperative style). But at base, describe your world.
86 'arity' means # of arguments
foo/1 - means foo(X), foo with 1 argument
foo//1 means the DCG foo with 1 semantic argument foo(X) --> ...
this idiom appears not only in docs, but in code like
:- dynamic foo/3.
87 DCG's are useful any time you want to transform a list to a list in some complex way. That includes, but isn't limited to, parsing text.
88 you can simplify writing parsers by first parsing to a tokenized format. discard comments, whitespace, parse string literal escapes and bundle up identifiers and operators
89 Left recursion is this pattern
foo --> foo, "x"
infinite loop - change to foo --> "x", foo. or use tabling.
Sometimes using tabling to fix can yield clearer, more intuitive DCG's
append([a,b],[c,d],[a,b,c,d]) - is this a partition?
append([a,b],[c,d],Z) - concatenate
append([a,b],Y,Z) - name lists that start a,b
append([a,b],Y,[a,b,c,d]) - suffix
append(X,Y,[a,b,c,d]) name the partitions of a,b,c,d
append(X,Y,Z) name pairs of lists and what they concat to
append(X,[c,d],Z) name lists that end c,d
append(X,[c,d],[a,b,c,d]) prefix
One predicate, 8 uses - multimodal predicates vastly simplify memorizing libraries.
control structures are evil. They make it in practice impossible for code to understand method/function bodies.
Prolog eschews control structures. Metapredicates undermine this, but meta_predicate saves the day.
93 In #Prolog you print error messages by passing a *semantic* term like error(evaluation_error(zero_divisor), context((/)/2, _9960)) to print_message/3 or throwing it. If you make a new message type, define how to print it in prolog:message//1
93b this separates concerns - detecting/defining error, converting to text, and displaying.…
94 In post 7.0 #SWIProlog dicts convert to JSON objects easily.
95 #SWIProlog has an XPATH library. Navigating XML is actually fun!
Recently the readline library was removed from #SWIProlog to avoid GPLing. Editline substitutes. Power readline users,…
On the site most pages are wiki pages, dynamically generated from the pldocs for their predicates.
#SWIProlog talks XML,CSV,ODS,JSON,ODBC,Pengines,HTTP,Java,C++,C,Protocol Buffers,RDF,RDFS,OWL,SGML,HTML,libedit,Markdown,SSL,OpenID,TIPC,Unicode,tar archives, and zip, out of the box.
In all my #prolog coding I've only once thought I'd have to use a library via another language. I was wrong -… There IS an interface to the OSC Linux sound control system.
100 #Prolog is neat.
You can try it now at or easily install using swivm
101… gets anywhere from 2 to 20 commits a day.
102 The #SWIProlog mascot is named Owlie. Like Prolog, he's knowledgable and wise. And #Prolog is a particularly good language for working with OWL, the semantic web reasoner.
Data - facts that reduce uncertainty.
Knowledge - data that can be reasoned about
Wisdom - knowledge that should be reasoned about
104 You can lazy-load read with phrase_from_file
105 There are Docker images for SWI-Prolog
106 If you want more OO feel and more type safety check out @LogtalkDotOrg
107 If you want strict compile time type safety and high performance, check out @MercuryLang
108 If you want great mobile dev check out @janburse Jekejeke Prolog…
109 #SWIProlog is one of the best languages for working with the semantic web. Check out this amazing interview with semweb guru @WGJBeek
110 #SWIProlog has a lot of sound and music libraries.
111 Reasoning can be forward. Start with premises, reason additional facts. I see it's raining, I infer the ground is wet. I infer the picnic's cancelled. I infer it's cloudy.
112 Reasoning can be backwards. I can get to work if my car works, I have enough gas, and the road is open. My car works. I will have enough gas if my tank is full (oops, it's empty), or if I fill the tank. ...
112b I can get to work if there's a road. if there's an open highway there's a road, but the highway's not open. I can get to work if there's a surface street, which there is.
So yes, I can get to work, by filling the tank and using surface street.
113 #Prolog is backwards chaining reasoning. CHR (comes with #SWIProlog), and ECLiPSe support forward chaining.
114 ECLiPSe is also good at constraint programming. GProlog also has some nice constraint systems. There's a massive field of constraint programming, see @constraints_cp
115 Constraint programming is useful for CAD systems - "this line is parallel to that line. It is 2 inches away"
116 Check out my tutorial on constraint programming. It'll make your world better. Or make you more frustrated with whatever you're programming in…
117 I've generated documentation dynamically by programmatically reading the code before. EG if you always use http_params/3 to get the query arguments, you can just find that in the code.
118 clause/2 will give you all the clauses in your program.... yeah... it'll do that...
119 "Innerds" like the built-in editor in #SWIProlog are made in a fairly transparent way. If you want to build a custom GUI you can embed pceEmacs in it.
120 #SWIProlog has an OO extension, pce. Atop that is XPCE, the GUI system. Sadly, it doesn't always live happily with modern multithreaded apps.
121 Paul Tarau's "engines' extension adds the ability to make thousands of tiny VM's
122 Pengines puts a sandboxed #prolog interactor on a remote system and then run real Prolog language queries against it.
Intro video on it
123 Talk by @mndrix about using #SWIProlog in production
124 If you can tolerate a bit of rollback and aren't expecting massive volume, you can eliminate the rear tier of your 3 tier web app by using library(persistancy)
125 RDF triples can be described using prefixes in #SWIProlog RDF code.
rdf(User, foaf:name, Name)
126 You can fiddle around with probabilistic logic online using
Of course cplint comes with #SWIProlog
127 You can log in to the (OpenID) website and post comments on most pages.
128 If you're not using swivm, the best way to get SWI-Prolog on linux is just to build from Github
The sane way to get Windows is use the binary
129 Some HUGE number of CS undergrads gets a terrrible 2 week intro to Prolog each semester. We're fighting uphill
130 @learnprolognow Is a cool book on #prolog. The #SWIProlog folks embedded SWISH pages in it so it's interactive, it's available here…
131 I have dreams of SWISH becoming a framework for building truly collaborative systems. I'd love to make something like @collabedit trivial to put up.
132 The semantics of bagof/3 are kind of mind bending. If you want something tamer, findall/3 covers the most usual case.
"The Craft of Prolog" by @NotDoctorOk is one of the true classics of Computer Science.
134 It's trivially easy to get bragging rights as a language contributor. Build #SWIProlog from sources and start learning. Sooner or later you'll find a minor annoyance. It's probably not hard to fix.
Submit a PR.
135 library(optparse) does a good job abstracting parsing command lines
136 a small annoyance of Prolog's way of doing metapredicates is wishing arguments were in another order, since call/n only adds to end.
library(yall) reorders args
137a in addition to unit tests, you can add custom 'lint' checkers.
Suppose you have some predicate that calls a service that might not be available, and so should only be called within some other with_remote_service metapredicate...
137b You could write a bit of code using goal_expansion to find the calls, collect the parents, and recursively apply, not passing through the with_remote_service metapred
137c if you reach some top entry point you've got a problem. Print an error message that includes the stack of calls
138 you can extend the syntax coloring in the editor
139 #SWIProlog has Scala like quasiquotes for HTML, Javascript, JSON, URI's, and you can make your own easily.
140 You can hook into darn near anything. Used unwisely, this can result in unmaintainable code, but if you need it, use it…
141 #prolog is incredibly DSL making friendly.…
142 Prolog gives proofs, not solutions. So if something can be proved two ways, it duplicates the solution. This is an annoyance to new #prolog programmers, but in the long run is the correct way
143 I've been working on a #Prolog comic. The more retweets this thread gets, the more I'm encouraged rto work on it
144 You can hook into comment reading, and make your own custom annotations
145 #prolog's philosophy is give you power, not safety. If you are complaining about the language, you can fix it. If you need types, go for it. If this would be easier in @morecobol , implement PIC clauses as a quasiquote.
146 You can click the query button in the debugger, enter a query, then ctrl-D to get back to debugging.
147 You can type e in the debugger, edit your code rigth there, C-c C-m make , click the edit mode toggle to get outta edit mode, and keep tracing.
148 If your state is stored in different modules than your code, you can rebuild the code without disturbing state. This means, eg that you don't do a bunch of UI actions in your compile cycle.
149 Prolog has 3 memory areas - Global memory, which is like the heap, Stack which is like the stack (doh) and trail, which records choice points.
Good Prolog implementations GC all of them
150 there are hundreds if not thousands of 'toy' prolog implementations. Use one of the mature distros. Prolog implementations in Java look convenient, but run slowly. Writing an indexer for Prolog is a hairy piece of hackery.
151 Prolog programs rarely have bugs caused by indenting issues, because there's rarely a need to indent more than one level.
(If you're beyond 2 and you're not in a data term instead of code, DEFINITELY make a helper predicate.)
coding Prolog, the language frequently points out logic errors to me. I start enumerating cases and go 'oh yeah, that case'
Even if you're not in prolog, disjunctive normal form is easier to read than an else-if tree.
imperative/functional programming is not 'simpler'. After years writing Prolog I needed to learn Scala. Coding a little game, I was way down in the stack and planning on just failing back if I didn't find a solution. Doh!😝🤪🤯
155 cuts eliminate all choice points created since the moment just before the predicate was entered - so all from the body, and a choice point from additional clauses.
156 If you're wondering how you got to a point where some unexpected value is passed, put in a conditional. If true, gtrace, if false, true (do nothing), compile, restart high enough up to catch it.
157 keeping your state on the stack gives cheap undo.Just get a user action, and leave a choice point. To undo, fail.
158 never add predicates with arbitrary functors at runtime. If you are recording things bob likes, don't just assert(apples), assert likes(apples) or likes(bob, apples). Most things are reified somehow.
159 A choice point does not imply a solution. It implies that the system can keep searching.
160 Clauses should generally be shorter and simpler than methods.
161 Interprolog's LPS system introduces a scheme for modeling a changing world as a 'logical contract'
162 one way to model state change is to model a mutator f(S, s) -> S' logically, then have a tail recursion that runs in it's own thread and reads messages from the thread message queue
162b You can make a number of these if your problem can be segmented, it doesn't have to be one giant block of handler code.
is adding moar #prolog tips as replies to this thread
163 apropos/1 will find predicates that match a partial name
164 #prolog often uses [k1-v1, k2-v2] type lists as key-value pairs sometimes with = as the joiner
there's a library to handle these
165 sorted lists with no duplicated elements are 'ordsets'. You can treat them as sets and do set operations on them
166 there are predicates to wire in your favorite editor to cooperate with #SWIProlog
The codemirror syntax coloring is used in SWISH, so it kept up to date.
167 looking at the sources of the libraries is a great way to learn.
168 Code is data - you can mix facts and rules.
ok_num(X) :- 1 is X % 2.
#prolog has a reputation for being slow. It *is* slow if a) you're using 1980's computers - Java woulda been slow then too. b) you leave lots of crazy choice points and have inefficient code.
If you're teaching #prolog buy Dr. Foobar a cup of coffee - and don't teach puzzles and tricks!…
171 This is a repeat-fail loop. It's one way to loop.
rf :- member(X, [a,b,c,d]), % choice points
172 if you need to loop and don't have a 'generator' (member/2 is the generator above) repeat/0 will give you an infinite number of choice points.
The Amzi corporation maintains a set of tutorials on Expert Systems in Prolog, taken from Dennis Merritt's book of that title. get the actual book, the online version omits a lot of needed info.
Sophia, the robot given citizenship in Saudi Arabia recently, was partly programmed in #prolog.
Oops - forgot the link to Expert systems in Prolog…
But do get the book…
175 #SWIProlog's module system is leaky encapsulation. You can call a private predicate if you need to other_module:private_predicate(42)
has a cool tutorial on modules…
177 if you want to do something like delegation, you can call reexport to make all the publics in a module appear as publics from another module.
Weirdly, this is often useful.
178a almost nothing is 'sacred' or 'special' in #prolog.
:- module(foo, []).
When the reader sees this it parses to ...
178b ':-'(module(foo, [])) and passes it to call.
If you wish to redefine a system predicate, redefine_system_predicate/1…
179 nb_setval and friends are a great substitute for asserta
180 never use assert/1. Use asserta/1 or assertz/1.
181 you can find yourself dragging the whole world along on the stack. b_setval and friends are ways to establish an environment.
Missing some Tweet in this thread?
You can try to force a refresh.
This content can be removed from Twitter at anytime, get a PDF archive by mail!
This is a Premium feature, you will be asked to pay $30.00/year
for a one year Premium membership with unlimited archiving.
Don't miss anything from @AnnieTheObscure,
subscribe and get alerts when a new unroll is available!
Did Thread Reader help you today?
Support us: We are indie developers! Read more about the story
Become a 💎 Premium member ($30.00/year) and get exclusive features!
Too expensive?
Make a small donation instead. Buy us a coffee ($5) or help for the server cost ($10):
Donate with 😘 Paypal or  Become a Patron 😍 on
Trending hashtags
Did Thread Reader help you today?
Support us: We are indie developers! Read more about the story
Become a 💎 Premium member ($30.00/year) and get exclusive features!
Too expensive?
Make a small donation instead. Buy us a coffee ($5) or help for the server cost ($10):
Donate with 😘 Paypal or  Become a Patron 😍 on