[ANN]: Abstract Logic Solver for Julia - AbstractLogic.jl

I would love any feedback people might have. I have spent a lot of time refining the package and making it potentially useful. I see it as a ready tool for solving, validating, and providing the basis for generating abstract reasoning problems.

Find it at: https://github.com/EconometricsBySimulation/AbstractLogic.jl

From the README.md

A Simple Example

A typical kind of problem which one might have encountered in an aptitude test
at some point in ones life might look like the following.

Peter is younger than Susan. Sam is younger than Susan but older than Ali.
Li is older than Ali younger than Peter.

Who must be the oldest?
a) Peter b) Susan c) Sam d) Li e) Ali f) Cannot Tell

Who must be the youngest?
a) Peter b) Susan c) Sam d) Li e) Ali f) Cannot Tell

Who could be the same age as Li?
a) Peter b) Susan c) Sam d) Ali e) Nobody f) Cannot Tell

The package AbstractLogic provides a tool for easily evaluating such problems.
First lets load in the feasible matches. Because there are 5 people in the
problem we can assign them 5 age categories which represent cardinal ordered
ages.

julia> using AbstractLogic
Start the repl in command prompt by typing `=`.

abstractlogic> Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5
Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5       feasible outcomes 3125 ✓        :4 2 4 3 4

abstractlogic> Peter < Susan; Sam < Susan
Peter < Susan            feasible outcomes 1250 ✓        :2 3 3 4 4
Sam < Susan              feasible outcomes 750 ✓         :4 5 4 5 4

abstractlogic> Sam > Ali; Li > Ali; Li < Peter
Sam > Ali                feasible outcomes 175 ✓         :1 3 2 3 1
Li > Ali                 feasible outcomes 121 ✓         :4 5 2 5 1
Li < Peter               feasible outcomes 13 ✓          :4 5 4 3 2

abstractlogic> search {{i}} > {{!i}}
Checking: Peter > Susan
Checking: Peter > Sam
...
Checking: Ali > Sam
Checking: Ali > Li

:Peter is a not match with 0 feasible combinations out of 13.
:Susan is a match with 13 feasible combinations out of 13.
:Sam is a not match with 0 feasible combinations out of 13.
:Li is a not match with 0 feasible combinations out of 13.
:Ali is a not match with 0 feasible combinations out of 13.

More Interesting Examples

The best way to see the functionality of AbstractLogic is to see it in action.

Snape’s potions problem in J.K. Rowling’s “Harry Potter”

June LSAC 2007 by the Law School Admission Council q1-5

June LSAC 2007 by the Law School Admission Council q6-10

June LSAC 2007 by the Law School Admission Council q11-17

14 Likes
julia> 
$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _  |  |
  | | |_| | | | (_| |  |  Version 1.2.0 (2019-08-20)
 _/ |\__ _|_|_|\__ _|  |  Official https://julialang.org/ release
|__/                   |

(v1.2) pkg> add AbstractLogic
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
ERROR: The following package names could not be resolved:
 * AbstractLogic (not found in project, manifest or registry)
Please specify by known `name=uuid`.


It is not registered.

pkg> add https://github.com/EconometricsBySimulation/AbstractLogic.jl
1 Like

I am not sure what the standards for publishing a registered package were or not. I would be happy to publish it. I have been holding off as I considered it in alpha testing mode.

Suggestions?

Alpha testing is a little early, you want to be confident that users will find it works, for the most part (so Beta). The quickest route is through writing tests that cover what you want to be sure works.

I think I have pretty good coverage of core features with my tests. I probably need to expand them to cover more though.

I think this package is definitely at a point where it can be registered if it has automated testing enabled.

1 Like

You want to setup automated testing, test coverage and doc building and add the badges in the readme.

For the doc iirc it will be automatically hosted on https://pkg.julialang.org/docs/ once registered, e.g. this minimal config file is sufficient to get your doc to work.

Otherwise this is up-to-date I think (there’s the commands for test coverage) : https://github.com/JuliaLang/Example.jl/blob/master/.travis.yml

You’ll also need to create accounts on travis-ci.org and coveralls to activate your repo.

1 Like

Travis CI is giving me this error. Failed all builds. Not sure were to start looking to debug this.

The command "julia --color=yes -e "if VERSION < v\"0.7.0-DEV.5183\"; Pkg.clone(pwd()); Pkg.build(\"${JL_PKG}\"); else using Pkg; if VERSION >= v\"1.1.0-rc1\"; Pkg.build(verbose=true); else Pkg.build(); end; end"" failed and exited with 1 during .
Your build has been stopped.

I think it’s because you have a Manifest.toml file in there, you can try to remove it.

Darn, deleted Manifest.toml but still error

You deleted the one in the docs, I was talking about this one.

Got Julia 1.1 passed and working on 1.2! Looks like it is passing! Thank you so much.

2 Likes

Awesome Travis CI and Coveralls up and running!

1 Like

Can anyone reproduce this problem?

abstractlogic> clear
Clearing Activeset

abstractlogic> Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5
Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5 	 Feasible Outcomes: 3125 	 Perceived Outcomes: 3125 ✓  	 :5 5 5 3 5

abstractlogic> Peter < Susan; Sam < Susan
Peter < Susan 		 Feasible Outcomes: 1250 	 Perceived Outcomes: 2000 ✓  	 :2 4 4 1 1
Sam < Susan 		 Feasible Outcomes: 750 	 Perceived Outcomes: 1600 ✓  	 :2 4 3 2 4

abstractlogic> Sam > Ali; Li > Ali; Li < Peter
Sam > Ali 		 Feasible Outcomes: 175 	 Perceived Outcomes: 540 ✓  	 :1 5 3 5 1
Li > Ali 		 Feasible Outcomes: 121 	 Perceived Outcomes: 432 ✓  	 :3 5 3 3 2
Li < Peter 		 Feasible Outcomes: 13 	 Perceived Outcomes: 48 ✓  	 :4 5 3 2 1

abstractlogic> search {{i}} > {{!i}}
Warning! Search Failed: UndefVarError(:replcmdverbose)

Fixed it! Sorry about that. Need to up my testing coverage.

Ok 88% coverage Travis CI building and testing properly. Now all i need is to figure out how to build my documentation. Seems Documenter won’t build on Windows.

I am trying to make sense of your package. It seems to me that the number of feasible outcomes is n^n which in this case is 3^3 == 27

abstractlogic> clear
Clearing Activeset

abstractlogic> a, b , c ∈ 1, 2, 3
a, b , c ∈ 1, 2, 3 	 Feasible Outcomes: 27 	 Perceived Outcomes: 27 ✓  	 :1 3 2

abstractlogic> a < c
a < c 			 Feasible Outcomes: 9 	 Perceived Outcomes: 12 ✓  	 :1 1 3

abstractlogic> check a == 1
check: a == 1 ... a == 1 			 Feasible Outcomes: 6 	 Perceived Outcomes: 6 ✓  	 :1 1 2
possible, 6 out of 9 possible combinations 'true'.

abstractlogic> check a == 2
check: a == 2 ... a == 2 			 Feasible Outcomes: 3 	 Perceived Outcomes: 3 ✓  	 :2 2 3
possible, 3 out of 9 possible combinations 'true'.

Trying to figure out what search is

abstractlogic> search == 1
  Checking: a == 1 Checking: b == 1 Checking: c == 1 

:a is a possible match with 6 feasible combinations out of 9.
:b is a possible match with 3 feasible combinations out of 9.
:c is a not match with 0 feasible combinations out of 9.

abstractlogic> search {{i}} == 1
  Checking: a == 1 Checking: b == 1 Checking: c == 1 

:a is a possible match with 6 feasible combinations out of 9.
:b is a possible match with 3 feasible combinations out of 9.
:c is a not match with 0 feasible combinations out of 9.

abstractlogic> search {{n}} == 1
Warning! Search Failed: ErrorException("type Nothing has no field match")

abstractlogic> search {{j}} == 1
  Checking: a == 1 Checking: b == 1 Checking: c == 1 

:a is a possible match with 6 feasible combinations out of 9.
:b is a possible match with 3 feasible combinations out of 9.
:c is a not match with 0 feasible combinations out of 9.

abstractlogic> search {{k}} == 1
Warning! Search Failed: ErrorException("type Nothing has no field match")

Okay, “search” likes {{i}} and like {{j}}
but it does not like {{n}} and not like {{k}}
I think search like character with a dot in it like i and j

Going through all 26 letters of the alphabet, search only likes {{i}} and {{j}} so that proves my hypothesis correct. What a mystic program.

Show is wonderful. It kinda shows the internal feasible states

abstractlogic> help show
  REPL: show 

  variantes: show, s 

  Print a table of 10 feasible results (head and tail).
abstractlogic> show
a b c
– – –
1 1 2
1 1 3
1 2 2
1 2 3
1 3 2
1 3 3
2 1 3
2 2 3
2 3 3

Showall is even more wonderful, I think I broke the internet running it.

abstractlogic> showall
ERROR: function showall does not accept keyword arguments
Stacktrace:
 [1] kwfunc(::Any) at ./boot.jl:332
 [2] (::getfield(AbstractLogic, Symbol("##abstractlogic#253#255")){getfield(AbstractLogic, Symbol("#keys#254"))})(::Bool, ::Bool, ::typeof(abstractlogic), ::String) at /Users/ssiew/.julia/packages/AbstractLogic/Rpe7G/src/repl/repl.jl:61
 [3] abstractlogic at /Users/ssiew/.julia/packages/AbstractLogic/Rpe7G/src/repl/repl.jl:33 [inlined]
 [4] parse_to_expr(::String) at /Users/ssiew/.julia/packages/AbstractLogic/Rpe7G/src/repl/replmaker.jl:4
 [5] #invokelatest#1 at ./essentials.jl:790 [inlined]
 [6] invokelatest at ./essentials.jl:789 [inlined]
 [7] (::getfield(REPL, Symbol("#do_respond#38")){Bool,typeof(AbstractLogic.parse_to_expr),REPL.LineEditREPL,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.2/REPL/src/REPL.jl:713

You can use check to do searches too

abstractlogic> check {{i}} == 1
check: {{i}} == 1 ... {{i}} == 1  >>> a == 1 >>> b == 1 >>> c == 1 
 		 Feasible Outcomes: 0 	 Perceived Outcomes: 0 X  	  [empty set]
false, 0 out of 9 possible combinations 'true'.

abstractlogic> check {{i}} >= 1
check: {{i}} >= 1 ... {{i}} >= 1  >>> a >= 1 >>> b >= 1 >>> c >= 1 
 		 Feasible Outcomes: 9 	 Perceived Outcomes: 12 ✓  	 :1 2 2
true, 9 out of 9 possible combinations 'true'.

{{i}} and {{j}} are similar but different wildcards. i fills in for any variable name while j only grabs the stem for variables with attributes

abstractlogic> bob.age, sue.age, stephen.age, peggy.age in 40, 50, 60
abstractlogic> bob.sex, stephen.sex in m
abstractlogic> sue.sex, peggy.sex in f
abstractlogic> {{j}}.sex == 'm' ==> {{j}}.age > 40 

abstractlogic> {{j}}.sex == 'm' ==> {{j}}.age > 40
{{j}}.sex == 'm' ==> {{j}}.age > 40  >>> bob.sex == 'm' ==> bob.age > 40 >>> sue.sex == 'm' ==> sue.age > 40 >>> stephen.sex == 'm' ==> stephen.age > 40 >>> peggy.sex == 'm' ==> peggy.age > 40
         Feasible Outcomes: 36   Perceived Outcomes: 36 ✓        :50 60 60 40 m m f f

Thanks for playing around with it. I’ll look into getting showall working.

Until showall is up in working. You can always swtich back to julia> replset[:,:,true] will collect all of the feasible values, julia> replset[:,:] returns all values of the domain, while julia> collect(replset) will return all values including their key values (true or false).