# AbstractLogic.jl

Welcome to AbstractLogic documentation!

This resource aims at teaching you everything you will need for using the intuitive Abstract Logic problem solver in the Julia language.

## Introduction

### What is an abstract logic solver?

Abstract logic problems come in many forms. This solver specifically is built to handle verbal abstract logic problems which have a finite number of possible permutations. Verbal abstract reasoning problems are often found in cognitive testing environments such as employee aptitude testing and prominently as a section on the Law School Entrance Exam.

### Why an abstract logic solver?

The cost of hand writing and evaluating items can be expensive. Abstract logic items are easy to write but relatively hard to evaluate. This package goes a long way to reducing the cost of evaluating items and is intended as a tool to aid in the generation of large batches of abstract reasoning items.

The need for large batches of items stems from a great deal of interest by test takers in illegally obtaining copies of items from high stakes exams. Cheating on high stakes exams is known to be common. This forces testing companies to spend a great deal of resources protecting their intellectual capital while also creating an environment in which they finds themselves vulnerable to accusations of secrecy. Producing tools that reduce the cost of generating and evaluating items has the promise of alleviating concerns over item exposure.

In addition to the benefit to testing companies of reduced cost items, reducing the cost of items has the promise of aiding in the production of items for the use by researchers and companies interested in evaluating the efforts and aptitudes of their employees who do not have the means of producing their own instrument or of obtaining and providing a secure environment for the deployment of a commercial instrument.

### 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.
1. Who must be the oldest?
a) Peter b) Susan c) Sam d) Li e) Ali f) Cannot Tell
2. Who must be the youngest?
a) Peter b) Susan c) Sam d) Li e) Ali f) Cannot Tell
3. 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.

Let's input this problem into Abstract Logic syntax.

```
julia> using AbstractLogic
Start the repl in command prompt by typing `=`.
abstractlogic> Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5 [clear]
Clear Workspace
Peter, Susan, Sam, Li, Ali ∈ 1, 2, 3, 4, 5 Feasible Outcomes: 3125 Perceived Outcomes: 3125 ✓ :1 3 4 1 1
abstractlogic> Peter < Susan; Sam < Susan
Peter < Susan Feasible Outcomes: 1250 Perceived Outcomes: 2000 ✓ :1 2 2 1 2
Sam < Susan Feasible Outcomes: 750 Perceived Outcomes: 1600 ✓ :1 2 1 5 4
abstractlogic> Sam > Ali; Li > Ali; Li < Peter
Sam > Ali Feasible Outcomes: 175 Perceived Outcomes: 540 ✓ :1 5 3 4 1
Li > Ali Feasible Outcomes: 121 Perceived Outcomes: 432 ✓ :1 4 3 5 1
Li < Peter Feasible Outcomes: 13 Perceived Outcomes: 48 ✓ :3 5 4 2 1
```

Now that we have input our constraints we can start asking our questions.

Question 1. Who must be the oldest?

```
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.
```

From this we can see that Susan is the oldest.

Question 2. Who must be is the youngest? To check who is the youngest we can do the same but this time setting `verbose=false`

to reduce the printing.

```
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 not match with 0 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 match with 13 feasible combinations out of 13.
```

The search function returns a ratio of feasible outcomes for each column relative to total outcomes. A zero means no feasible combination exist that match while a 1 indicates a 100% match.

Question 3. Who could be the same age as Li?

```
abstractlogic> search {{i}} = Li
Checking: Peter = Li Checking: Susan = Li ... Checking: Li = Li Checking: Ali = Li
:Peter is a not match with 0 feasible combinations out of 13.
:Susan is a not match with 0 feasible combinations out of 13.
:Sam is a possible match with 5 feasible combinations out of 13.
:Li is a match with 13 feasible combinations out of 13.
:Ali is a not match with 0 feasible combinations out of 13.
```

From the results we can see that Sam could share ages with Li.

But Abstract Logic can handle problems much more complex then simple inequalities!

### A More Complex Example

```
You would like to figure out your plans for the evenings this week. Each evening
can do only one activity at most. There are only four options for what you can do
each night: call home, work out, homework, or eat out with friends.
Each week begins on Monday and ends on Sunday.
Your schedule is subject to the following constraints:
You do homework at least twice a week
You work out at least twice a week
You do not work out on sequential days
You only eat out if the next day you work out.
You must call home at least once and at least three days after the last call.
Whatever you do on Fri must be different from what you do on Sat or Sun.
You must do homework at least one night on Monday, Tuesday, or Wednesday
You eat out at least twice per week.
Questions:
1. Given these constraints what is the most number of times you can work out each week?
a) two b) three c) four
2. If you do homework on Monday what must be true?
a) Friday you do not do homework
b) Wednesday you do not call home
c) Saturday you do not workout
d) Tuesday you do not workout
3. Which of the following must be true?
a) If you call home on Mon then your Tue and Fri activity must be the same.
b) If you call home on Tues then your Mon and Fri activity must be the same.
c) If you call home on Wed then your Mon and Sat activity must be the same.
d) If you call home on Fri then your Tues and Sun activity must be the same.
e) If you call home on Sat then your Mon and Wed activity must be the same.
```

Let's input this problem into Abstract Logic syntax.

```
julia> using AbstractLogic
Start the repl in command prompt by typing `=`.
abstractlogic> mo, tu, we, th, fr, sa, su ∈ call, gym, hmwk, eat [clear]
Clear Workspace
mo, tu, we, th, fr, sa, su ∈ call, gym, hmwk, eat Feasible Outcomes: 16384 Perceived Outcomes: 16384 ✓ :eat hmwk eat eat call hmwk eat
```

You do homework at least twice a week

```
abstractlogic> {{i}} = 'hmwk' {{2,}}
{{i}} = 'hmwk' {{2,}} >>> mo = 'hmwk' >>> tu = 'hmwk' ... >>> sa = 'hmwk' >>> su = 'hmwk' {{2,∞}}
Feasible Outcomes: 9094 Perceived Outcomes: 16384 ✓ :eat call hmwk hmwk gym gym call
```

You work out at least twice a week

```
abstractlogic> {{i}} = 'gym' {{2,}}
{{i}} = 'gym' {{2,}} >>> mo = 'gym' >>> tu = 'gym' ... >>> sa = 'gym' >>> su = 'gym' {{2,∞}}
Feasible Outcomes: 4172 Perceived Outcomes: 16384 ✓ :gym hmwk hmwk eat gym eat gym
```

You do not work out on sequential days

```
abstractlogic> {{i}} == 'gym' ==> {{i}} != {{i+1}}
{{i}} == 'gym' ==> {{i}} != {{i+1}} >>> mo == 'gym' ==> mo != tu >>> tu == 'gym' ==> tu != we ... >>> fr == 'gym' ==> fr != sa >>> sa == 'gym' ==> sa != su
Feasible Outcomes: 2302 Perceived Outcomes: 16384 ✓ :gym call hmwk eat hmwk call gym
```

You only eat out if the next day you work out. The `!`

in `{{i+1!}}`

tells the spawner to swap `OUTOFBOUNDS`

with 999 for comparison purposes.

```
abstractlogic> {{i}} = 'eat' ==> {{i+1!}} = 'gym'
{{i}} = 'eat' ==> {{i+1!}} = 'gym' >>> mo = 'eat' ==> tu = 'gym' >>> tu = 'eat' ==> we = 'gym' ... >>> sa = 'eat' ==> su = 'gym' >>> su = 'eat' ==> 999 = 'gym'
Feasible Outcomes: 936 Perceived Outcomes: 12288 ✓ :call gym hmwk gym hmwk hmwk gym
```

Since the week ends on Sunday we cannot count on working out on Monday. This constraint is redundant since this has already been restricted from the `!`

in the last expression.

```
abstractlogic> su != 'eatout'
su != 'eatout' Feasible Outcomes: 936 Perceived Outcomes: 12288 ✓ :hmwk gym hmwk call call hmwk gym
```

You must call home at least once and any follow up calls have to be three after the last call.

```
abstractlogic> {{i}} = 'call' {{1,}}; {{i}} = 'call' ==> {{<i+3,>i}} != 'call'
{{i}} = 'call' {{1,}} >>> mo = 'call' >>> tu = 'call' ... >>> sa = 'call' >>> su = 'call' {{1,∞}}
Feasible Outcomes: 830 Perceived Outcomes: 12288 ✓ :gym call gym hmwk call call hmwk
{{i}} = 'call' ==> {{<i+3,>i}} != 'call' >>> mo = 'call' ==> tu != 'call' >>> mo = 'call' ==> we != 'call' ... >>> fr = 'call' ==> su != 'call' >>> sa = 'call' ==> su != 'call'
Feasible Outcomes: 496 Perceived Outcomes: 12288 ✓ :call gym hmwk hmwk hmwk gym hmwk
```

Let's check if that least command is doing what we expect. Lets restrict ourselves to the cases in which we call home at least twice.

```
abstractlogic> {{i}} = 'call' {{2,}}
{{i}} = 'call' {{2,}} >>> mo = 'call' >>> tu = 'call' ... >>> sa = 'call' >>> su = 'call' {{2,∞}}
Feasible Outcomes: 176 Perceived Outcomes: 12288 ✓ :call hmwk gym hmwk call gym hmwk
```

Let's see what they look like. Yeap, none of them feature calls closer than 3 days apart.

```
abstractlogic> show
Showing 10 of 176 rows
mo tu we th fr sa su
–––– ––– –––– –––– –––– –––– ––––
call gym hmwk call gym hmwk call
call gym hmwk call gym hmwk gym
call gym hmwk call gym hmwk hmwk
call gym hmwk call hmwk gym call
call gym hmwk call hmwk gym hmwk
⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮
eat gym call hmwk gym hmwk call
eat gym call hmwk hmwk call gym
eat gym call hmwk hmwk gym call
eat gym hmwk call gym hmwk call
eat gym hmwk call hmwk gym call
```

```
abstractlogic> back
Last command: "{{i}} = 'call' {{1,}}; {{i}} = 'call' ==> {{<i+3,>i}} != 'call'" - Feasible Outcomes: 496 Perceived Outcomes: 12288 :call call gym gym hmwk hmwk hmwk
```

Whatever you do on Friday must be different from what you do on Saturday or Sunday.

```
abstractlogic> fr != sa, su
fr != sa, su Feasible Outcomes: 319 Perceived Outcomes: 12288 ✓ :gym call hmwk hmwk hmwk gym call
```

You must do homework at least one night on Monday, Tuesday, or Wednesday

```
abstractlogic> mo | tu | we = 'hmwk'
mo | tu | we = 'hmwk' Feasible Outcomes: 278 Perceived Outcomes: 12288 ✓ :call hmwk gym eat gym hmwk hmwk
```

Would like to eat out at least twice per week.

```
abstractlogic> {{i}} = 'eat' {{2,}}
{{i}} = 'eat' {{2,}} >>> mo = 'eat' >>> tu = 'eat' ... >>> sa = 'eat' >>> su = 'eat' {{2,∞}}
Feasible Outcomes: 18 Perceived Outcomes: 6912 ✓ :eat gym hmwk eat gym hmwk call
```

Now for us to address the questions:

```
abstractlogic> silence
Silencing REPL print. Reverse with command 'noisy'
```

Question 1. Given these constraints what is the most number of times you can work out each week?

a) two b) three c) four

```
abstractlogic> check: {{i}} = 'gym' {{2}}
true
```

Question 2. If you do homework on Monday what must be true?

First we will preserve the current state of the data so that we can reverse the preserve.

```
abstractlogic> preserve
Preserving State
abstractlogic> mo = 'hmwk'
```

a) Tuesday you do not eat out

```
abstractlogic> prove: tu != 'eat'
false
```

b) Wednesday you do not call home

```
abstractlogic> prove: we != 'call'
true
```

c) Friday you do not do homework

```
abstractlogic> prove: fr != 'hmwk'
false
```

d) Saturday you do not workout

```
abstractlogic> prove: sa != 'gym'
false
```

Return to the state before requiring us to do homework on Monday.

```
abstractlogic> restore
Restoring State - Feasible Outcomes: 18 Perceived Outcomes: 6912 :call eat eat gym gym hmwk hmwk
```

Question 3. Which of the following must be true? a) If you call home on Monday then your Tuesday and Friday activity must be the same.

```
abstractlogic> prove: mo == 'call' ==> tu == fr
false
```

b) If you call home on Tuesday then your Monday and Friday activity must be the same.

```
abstractlogic> prove: tu == 'call' ==> mo == fr
false
```

c) If you call home on Wednesday then your Monday and Saturday activity must be the same.

```
abstractlogic> prove: we == 'call' ==> mo == sa
true
```

d) If you call home on Friday then your Tuesday and Sunday activity must be the same.

```
abstractlogic> prove: fr == 'call' ==> tu == su
false
```

e) If you call home on Saturday then your Monday and Wednesday activity must be the same.

```
abstractlogic> prove: sa == 'call' ==> mo == we
false
```