GithubHelp home page GithubHelp logo

asmaloney / gactar Goto Github PK

View Code? Open in Web Editor NEW
14.0 6.0 4.0 16.37 MB

๐Ÿง  A tool for creating & running basic ACT-R models on multiple implementations using a single declarative file format

License: MIT License

Go 85.76% HTML 0.24% CSS 0.48% JavaScript 0.24% Python 2.46% Vue 6.48% SCSS 0.55% Makefile 0.16% TypeScript 3.29% Common Lisp 0.35%
act-r cognitive-modelling cognitive-architecture cognitive-science proof-of-concept cogsci

gactar's Introduction

Over time, I plan to move as many of my repos as feasible to GitLab and Codeberg.

gactar's People

Contributors

asmaloney avatar ren-oz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gactar's Issues

Look at logging levels for each framework

Right now this:

actr { log: true }

turns on logging at the top level of the ccm framework.

Need to look at each framework and figure out a strategy for this - maybe logging levels (info, full)?

Related to #13

Set a default memory and/or buffer?

Maybe allow declaring one memory and one buffer as default?

buffers {
    goal: {
        default: true
    }

    retrieve{}
}

memories {
    memory {
        buffer: retrieve
        default: true
    }
}

Then we can shorten production statements:

set field 4 of goal to 'busy'
recall `count ?next ?` from memory

would become:

set field 4 to 'busy'
recall `count ?next ?`

It would make reading productions less explicit which may be a drawback.

I kind of like the memory one, but not the buffer. I think because the memory feels more like a global in the context of the production statements.

Review memory module options

Now that we have it, the modules section is a better place for configuring the memory module. (Done)

Also need to review the config params and see what we can use across the three frameworks, and implement them.

Running a model assumes a buffer named "goal"

When generating the code for running the model, gactar currently assumes there is a goal buffer and sets that.

Instead, we should either:

  • make the goal buffer implicit (i.e. always create it and expect the models to use it)
  • explicitly identify which buffer is the goal in the declaration:
buffers {
    goal: {
        goal: true
    }

    retrieve{}
}
  • look for a buffer named goal & use it if it exists, and override/fall back on explicitly identifying it as above

tmp path

Right now gactar is putting generated files in tmp next to the executable.

Should probably default to putting them in an actual temporary directory (and clean up afterwards).

Allow override of this on the command line because it's useful to look at the generated code.

This is related to #18.

Convert "examples" section to use patterns

Right now they are strings which we have to handle specially. Using patterns would also have the benefit of ensuring they are correct w.r.t. the currently declared chunks, making it harder for the examples to become stale.

Somewhat related to #24

{web} Add code editor

Using a proper js code editor e.g. CodeMirror would provide a much better UX.

This would require setting up node.js (probably using docker) to build the built-in web pages instead of using the simple hand-coded html/css/js that's there now. We can avoid the webpack monstrosity by using something like rollup.js.

Export amod to other formats (JSON, XML)

(Suggestion from @kenwebb.)

Add translating/exporting of the amod file to other open formats such as XML and JSON. This would allow other tools to use the amod models without having to parse the amod format and validate the model.

I'm not opposed to this idea in principle. While implementing this should not be too complex, it would add a maintenance burden - any time the amod format or the internal representation changed, the exporters would need updating.

Rather than implementing something that might be useful, I think it makes sense to let the amod format mature a bit and wait for a project that would actually use this.

Happy to accept feedback/discussion here!

{vanilla} Fix print output

If we have this in the amod file:

print 'The category is' ?cat

It is translated to this in the vanilla framework:

!output!	("The category is" =cat)

which doesn't output properly because ACT-R thinks that the quotes mean there's formatting going on.

If the first item given in a list to an !output! action is a string then that string is assumed to be a format specification.

So we get this output:

The value is

If we don't quote the string when we output it, we get this:

!output!	(The category is =cat)

but then the output does not maintain formatting:

THE CATEGORY IS "animal"

So what we have to do is:

  • if the print statement does not contain variables, output it like this:
    !output!	("Some string maybe with non-alpha chars ?foo-%")
    
  • if it does contain variables, we need to construct the formatting string and output something like:
    !output!	("The category is ~a" =cat)
    
  • note that we might have print 'The category is ' ?cat ' ( ' ?sub ')' which would need to be output as:
    !output!	("The category is ~a (~a)" =cat =sub)
    

{vanilla} Look at state handling w.r.t. failure

When running semantic.amod, my generated model produces this for vanilla:

?retrieval>
	state error

and it doesn't seem to match the fail production.

In the vanilla ACT-R tutorials, it uses:

?retrieval>
 	buffer      failure

Need to look this up to see what's happening...

pyactr seems to work using state error.

{web} Display generated code

Probably useful to be able to display the generated code as well...

Need the webserver to include it in the response.

Updating components

Need to provide a way to update various components that we've automatically downloaded...

Probably a script per component to run whatever download/install we need to do.

This is sounding more like a package manager - want to avoid this!

Multiple memories?

Can we actually have a model with multiple memories?

If not, we can simplify the config by allowing only one and simply the recall statement as in #8.

{ccm} Add tracing feature

It would be useful to trace the changes in buffers as production rules fire.

As far as I can tell, right now this isn't possible "out of the box" without modifying ccm because we don't have a get() method on Buffer.

If we had that method, we could add something like this to the productions:

print('[start] goal: "' + str(goal.get()) + '" retrieve: "' + str(retrieve.get()) + '"')

to get some useful trace output:

[start] goal: "countFrom 2 5 counting" retrieve: "None"
2
[increment] goal: "countFrom 3 5 counting" retrieve: "count 2 3"
3
[increment] goal: "countFrom 4 5 counting" retrieve: "count 3 4"
4
[increment] goal: "countFrom 5 5 counting" retrieve: "count 4 5"
5
[stop] goal: "None" retrieve: "count 5 6"
end...

(Side note: I tried making a method trace() to be called for each production, but the way the ccm is implemented it doesn't seem to be possible. So it means outputting the print call directly at the end of each production.

Look at paths

I've been more-or-less working with the assumption that we are using the python virtual environment.

Decide if that will be a requirement!

If it's not, we will need to review all path info and possibly provide extra flags to set them all.

Handle "print" without args

Should be able to call print without args to output a blank line.

Need to fix the parser and check for nil Args in places.

Parse patterns separately?

Maybe split the parser to handle the file format and the patterns separately?

It would be useful to be able to take the goal the user wants to set and parse it by itself.

Right now the goal is handled differently in different frameworks. Providing a parse would handle this consistently and possibly provide better error messages.

Add check for unused pattern variables

e.g.:

match {
    goal [add: ?num1 ?num2 ?count ?sum]
    retrieval [count: ?count ?next]
}
do {
    set count of goal to next
    recall [count: ?sum ?]
}

In this case, ?num1 and ?num2 are unused and should be ?.

This can be tricky because we need to check for this:

goal [add: ?num1 ?num2 ?num2 ?sum]

In this case, ?num1 is unused, but ?num2 is important because the two slots must match.

{pyactr} Incorrect result for addition2 example

When run with the example goal, pyactr produces:

...
(0.3, 'retrieval', 'RETRIEVED: addition_fact(addend1= 3, addend2= 4, sum= 7)')
(0.3, 'goal', 'MODIFIED')
(0.3, 'retrieval', 'START RETRIEVAL')
(0.3, 'PROCEDURAL', 'CONFLICT RESOLUTION')
(0.3, 'PROCEDURAL', 'RULE SELECTED: addTensDone')
(0.35, 'retrieval', 'RETRIEVED: None')
(0.35, 'PROCEDURAL', 'RULE FIRED: addTensDone')
(0.35, 'goal', 'MODIFIED')
(0.35, 'PROCEDURAL', 'CONFLICT RESOLUTION')
(0.35, 'PROCEDURAL', 'NO RULE FOUND')
final goal: add_pair(carry= nil, one1= 6, one2= 7, one_ans= 3, ten1= 3, ten2= 4, ten_ans= 7)

The retrieval should have matched addition_fact( 1 7 8 ), which would give the correct result with ten_ans=8.

Both other frameworks are correct. Here's vanilla ACT-R:

...
     0.350   DECLARATIVE            start-retrieval
     0.350   PROCEDURAL             CONFLICT-RESOLUTION
     0.400   DECLARATIVE            RETRIEVED-CHUNK FACT_3
     0.400   DECLARATIVE            SET-BUFFER-CHUNK RETRIEVAL FACT_3
     0.400   PROCEDURAL             CONFLICT-RESOLUTION
     0.450   PROCEDURAL             PRODUCTION-FIRED ADDTENSDONE
8 3 

The generated code for the productions in pyactr and vanilla ACT-R look the same.

Consider changing syntax of patterns

The current syntax feels a bit heavy with backticks everywhere.

`countFrom( 2 5 starting )`

Consider just removing them (like chunk declarations) since we can now parse using ')':

countFrom( 2 5 starting )

Consider changing the parens to square brackets so they look less like function:

countFrom[ 2 5 starting ]

Allow/require commas?:

countFrom[ 2, 5, starting ]

Pattern semantics

Need to figure out what pattern constructs such as busy?tenAns and None?tenAns mean in the ccm framework.

These are not currently handled in pyactr and vanilla.

"set" syntax

Currently a set statement looks like this:

set start of goal to next

Consider two changes:

  • to make it clearer, use a var instead of an id (possibly get rid of id as an option here?):
    set start of goal to ?next
    
  • and make more succinct with:
    set goal.start to ?next
    

This would make the set statement cleaner because then we would have:

set <buffer> to <pattern>

and

set <buffer>.<slot> to (number|string|var)

Add optional scripts to install sbcl (lisp)

If using the virtual env, it's convenient to automatically download and install sbcl. Unfortunately a generic script is difficult to write because of all the platforms/architectures, but maybe it can be improved over time with input from people on Linux and Windows.

Read initializations from file

If there is a lot of data to initialize, writing it all in the amod file is impractical. So instead of hard-coding specific file formats, provide an API and allow plugins to read the data - possibly with something like go-plugin. If done properly, this would allow writing plugins in almost any language.

Then the init section might look like this:

memory {
    reader: my-csv-plugin
    files {
        'file name 1'
        'file name 2'
    }
}

Where reader might be an external plugin or an internal one (i.e. flat text file).

Currently the python backend has to write these out like this:

	def init():
		memory.add('count 0 1')
		memory.add('count 1 2')
		memory.add('count 2 3')
		memory.add('count 3 4')
		memory.add('count 4 5')
		memory.add('count 5 6')
		memory.add('count 6 7')
		memory.add('count 7 8')

Which is also impractical. So we would have to figure out how to handle this more intelligently.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.