evaluator can have some side effect (IO)
support "main :- ..." style entry point
support built-in predicate (as of now, only write is supported)
DSL for built-in predicates
use exit value to tell unification result
use mtl instead of transformers library
implement cut operator using call/cc
testClause -> unifyClause