Modeling creativity with a semantic network of common sense

  Tom De Smedt (Computational Linguistics Research Group, University of Antwerp)
  Modeling Creativity: Case Studies in Python, chapters 4 & 5, pp. 78–80, 86–96
 

Computational creativity is a multidisciplinary field that studies creativity using techniques from artificial intelligence (AI), and drawing from psychology, cognitive science and the arts. Researchers in this field are interested in the theoretical concerns of creativity as well as developing computer models that exhibit, generate and evaluate creativity.

So what is creativity? What is a creative idea? Let us consider the mind as a search space (Boden, 2003): a roadmap of concepts with paths in between (e.g., highways, streets and trails), connecting the concepts that are related to each other. How many concepts are represented in the search space (i.e., how far the map spans) depends on knowledge and experience. How each concept relates to other concepts depends on education, environment and personality. If we think about a cat, we might recall related concepts such as dog and mouse. These are easier to reach from cat than toaster. If you once owned a cat, thinking about your cat could also recall memories of a toaster: cat → my cat → 6 a.m. meowing → breakfast → toast, and so on. Because we cannot examine our own mind as a whole, neither can we "see" the search space as a whole. But we can wander along its paths, consciously or unconsciously. Each concept activates new associative paths to follow, by circumstance, similarity or mediation (Mednick, 1962, Balota & Lorch, 1986). Some paths may lead us to explore a part we didn’t even know was there. Some paths may be too long, too old or too unreliable to investigate right now. Some will lead to a dead end or run in circles. 

As more paths are traversed – as more related concepts get involved – an idea grows. Short paths to nearby concepts yield commonly available associations. For example: cats chase mice. Mundane ideas come to mind first, and then with effort more novel ideas (Osborn, 1963). For example: a hungry cat makes a good alarm clock. Distant or atypical relations yield more creative ideas (Schilling, 2005) but come slower (Jung-Beeman et al., 2004). More relations in a larger search space enable more creative ideas. 

The search space can be traversed in different ways, using different thinking styles. A thinking style is a search strategy defined by rules and constraints that makes analogical pattern matching possible. Thinking styles primarily include unconscious, associative heuristics (shortcuts) such as intuition, rules of thumb, trial and error and common sense (Gilovich, Griffin & Kahneman, 2002). A conscious thinking style can be constructed from a logical rule such as find as many as possible or find the most unusual, combined with a constraint such as pet or loud. For example, possible pets we can think of right now are cat, dog, fish, parrot and so on. Unusual and loud pets we can think of include rooster, tiger, dinosaur and, after giving it some more thought, a miniature Darth Vader. The last specimen is an example of conceptual blending.  

Conceptual blending (Koestler, 1964, Lakoff & Johnson, 1980, Fauconnier & Turner, 2003) explores how concepts can be combined into new meaning. Fauconnier & Turner propose the idea of a blended search space: an ad hoc mental pocket where concepts are brought together and blended based on shared similarities. An example is the "house" pretend game. Various dolls and Mr. Bear are seated around a small table. They are inert of course, and there is no real tea in the teapot. But the child playing the game can project what it knows from real life onto the scene. She herself is now the mom, Mr. Bear the dad, and the dolls are children that have to sit up straight and behave before being served invisible tea. Distinct concepts from the real world – family members and toys – are blended together in a pretend space. Dad’s voice is mapped onto Mr. Bear. The dolls are reprimanded for their table manners in a way the girl would be in real life. But events in the pretend space are also allowed to run their own course; perhaps the dolls will rebel and fly off on their little ponies.

In this case study, we will model a concept search space using the pattern.graph module. Concepts are related to each other in a semantic network (Quillian, 1968; Sowa, 1987). For example, a doll concept can be modeled as: doll is-a toy, silent is-property-of doll, doll is-related-to girl. A semantic network is a specific type of graph data structure. A graph is a network of nodes and edges (connections between nodes). Each node represents a concept (e.g., doll) and each edge has a type (e.g., is-part-of). Computational techniques from graph theory can be used to find important nodes (centrality) or paths between the nodes (shortest path).

Our semantic network, called perception (De Smedt et al., 2013), stores knowledge about what things look and feel like. The database has about 9,000 manually annotated relations of the types is-a, is-part-of, is-opposite-of, is-property-of, is-related-to, is-same-as and is-effect-of between 4,000 mundane concepts (cat, doll, pasta, rain, and so on). Relation types are distributed across 10 contexts. A portion is uncategorized. The table below shows a general breakdown. The data is available by means of an online visualizer where new relations can be added to the semantic network. The visualizer shows the network using a force-directed algorithm (Hellesoy & Hoover, 2006). Following is an algorithm for comparing and shifting concepts in the semantic network, based on how the concepts look and feel. The analogies that it can generate are limited by the knowledge representation (i.e., 9,000 relations). 


The online visualizer is available at: http://www.nodebox.net/perception.

  is-a is-part-of is-opposite-of is-property-of is-related-to is-same-as
Culture 573 491 25 1,060 1,060 74
Nature 673 222 10 640 364 31
Properties 29 5 98 303 258 35
People 340 44 3 80 91 13
Geography 233 292 0 36 11 3
Media 109 75 2 148 143 5
History 33 35 1 32 86 9
Emotion 28 18 3 66 72 3
Sound 24 23 0 44 29 1
Science 12 26 1 33 38 1

Distribution of relations by context. The properties context is reserved for inter-adjective relations such as slow is-property-of bored. The is-effect-of relation is omitted; it contains very little data for now.
 

If a rocket is fast and hot, then what colors evoke speed and heat and might be suitable for a rocket toy? Since there is no right or wrong answer, this problem requires a divergent approach. Our algorithm could help discover a feasible solution to these so-called wicked problems – assignments in a social context with no clear solution (Rittel & Webber, 1973; Buchanan, 1992). If the toy company hires an artist to design a toy rocket, they could criticize her sketches in many ways (e.g., it looks a little menacing because too realistic). But probably not because the rocket design has bright red and yellow colors, which can be linked to heat, power, the sun, intensity, courage, and so on. The design choice of using red and yellow colors is a credible step towards a solution.

 


Semantic network

The pattern.graph module has a Graph object from which we can start:

from pattern.graph import Graph

g = Graph() 
g.add_edge('doll', 'toy', type='is-a') # doll is-a toy 
g.add_edge('silent', 'doll', type='is-property-of') 
g.add_edge('doll', 'girl', type='is-related-to') 

node = g['doll'] 
print node.id 
print node.links 

The node’s id is "doll". The node's links is a list of directly related nodes: [Node(id='toy'), Node(id='silent'), Node(id='girl')]. But we don’t want to define all the relations by hand; the perception database is included in Pattern as a CSV-file that we can easily import:

from pattern.graph import Graph 
from pattern.db import CSV 
 
g = Graph() 
 
data = 'pattern/graph/commonsense/commonsense.csv' 
data = CSV.load(data) 
for concept1, relation, concept2, context, weight in data: 
    g.add_edge( 
        concept1, 
        concept2, 
          type = relation, 
        weight = min(int(weight) * 0.1, 1.0)) 

In order to compare concepts, we will use a combination of graph theoretic methods: spreading activation, taxonomies, subgraph partitioning, betweenness centrality and shortest path finding.

 


Concept halo

"What is a cat?" To answer this kind of question, we need to know how concepts relate to cat in the semantic network. Each concept is surrounded by related concepts that reinforce its associative meaning: catpurr, catmouse, furrycat, and so on. The commonsense halo (Hofstadter, 1985) is the concept itself, its directly related concepts, concepts related to those concepts, and so on, as deep as the representation requires. This is called spreading activation (Collins & Loftus, 1975; Norvig, 1987). When asked about mice, people can readily come up with closely related concepts such as cats and cheese, but it takes longer to come up with less obvious concepts (e.g., gene) because there are more intermediary steps in the semantic chain. Activation spreads out from the starting concept in a gradient of decreasing relatedness.

Spreading activation can be implemented simply using the Node.flatten() method:

def halo(node, depth=2): 
    return node.flatten(depth)

The depth of the halo is an arbitrary choice. If it is too small, the concept will be underspecified. If it is too broad the halo will include irrelevant concepts. We use depth=2. In this case the halo is already rather broad: halo(g['cat']) yields over 350 concepts including elegant, furry, tail, milk, sleep, explore, but also quantum theory and, oddly, french fries. But this is beneficial: there will be more salient properties in the halo.

 


Concept field

"What are creepy-looking animals?" To answer this kind of question we need to be able to compare each specific animal to all other animals. Some concepts belong to the same class or taxonomy. Cats, dogs, fish and squirrels are examples of animals – essentially all concepts with an implicit or explicit is-a relation to animal in the semantic network. Such a collection is also known as a semantic field (Brinton, 2000), a set of words that share a common semantic property, related to hyponymy but more loosely defined. So we need a field() function that returns a list with ['cat', 'dog', ...] when given 'animal' and sort it by creepiness.

Retrieving such a list is not hard to accomplish using a combination of Graph and Node methods. The Node.flatten() method returns a list containing the given node (depth=0), any nodes connected to it (depth=1), and so on. We can supply a filter function to restrict which edges are traversed. In our case, we only follow is-a relations. The Graph.fringe() method returns a list of nodes with a single edge (depth=0), any nodes connected to these nodes (depth=1), and so on. A combination of the two methods yields the "outer rim" of a node’s taxonomy, which is a good approximation of our semantic field:

def field(node, depth=3, fringe=2): 
    def traversable(node, edge): 
        return edge.node2 == node and edge.type == 'is-a' 
    g = node.graph.copy(nodes=node.flatten(depth, traversable)) 
    g = g.fringe(depth=fringe) 
    g = [node.graph[n.id] for n in g if n != node] 
    return g
 

Concept properties

"How do cats and dogs compare?" For one, they both have a tail. Both of them are also furry, and they are both kept as pets. This is a featural approach to similarity (Tversky, 1977): comparing concepts by looking at the features or properties that they have in common. There are other measures of similarity, but in our setup we will use the feature approach because it is simple to implement. In the semantic network, some concepts (typically adjectives) are properties of other concepts. They describe what something looks or feels like: romantic is-property-of France, fast is-property-of rocket, dark is-property-of evil, evil is-property-of Darth Vader, and so on. If we can find the properties (e.g., romantic, fast, dark, evil) that define each concept we can construct an algorithm to compare them. The feature approach is our model's thinking style.

First, we store all the left-hand concepts that occur in is-property-of relations in a PROPERTIES dictionary. Dictionaries in Python are faster for lookup than lists:

PROPERTIES = [e.node1.id for e in g.edges if e.type == 'is-property-of'] 
PROPERTIES = dict.fromkeys(PROPERTIES, True) 

We can then implement a properties() function that, given a concept, extracts its latent properties from the concept halo. Note how we sort the results by betweenness centrality (Brandes, 2001) using Node.centrality (= a value between 0.0 and 1.0). This means that properties more central in the halo will appear first in the list:

cache = {} # Cache results for faster reuse.
 
def properties(node): 
    if node.id in cache: 
        return cache[node.id] 
    g = node.graph.copy(nodes=halo(node)) 
    p = (n for n in g.nodes if n.id in PROPERTIES) 
    p = reversed(sorted(p, key=lambda n: n.centrality)) 
    p = [node.graph[n.id] for n in p] 
    cache[node.id] = p 
    return p 

In perception, an animal that is semantically similar to a sword would be a hedgehog, since: sharp is-property-of sword, and also sharp is-property-of spine is-part-of hedgehog. The hedgehog’s prickly spines are used as an associative bridge. This is a fine observation as it is, but what we may have wanted was a fairy-tale dragon. Whether or not a concept appears in a fairy tale is not expressed by is-property-of relations, so this will never happen. The model uses a script (Schank & Abelson, 1977) to explore the network. A script is a fixed sequence of commands for decision-making. In the similarity() function given below, the use of properties() is hard-coded.

This does not pertain very well to the agility of the mind, but it makes the algorithm easier to study. We can see how it would not be hard to adapt the code to incorporate (or evolve) other scripts besides our featural approach, by adapting the properties() function.

 


Concept similarity

Similarity between two concepts is measured as the distance between their properties. The similarity() function retrieves the k most central properties in each concept’s halo. It then measures the length of the shortest path (Dijkstra, 1959) connecting each two properties, preferring to traverse is-property-of relations over other relations. This yields a higher value for more similar concepts (lower value for distinct concepts):

def similarity(node1, node2, k=3): 
    g = node1.graph 
    h = lambda id1, id2: 1 - int(g.edge(id1, id2).type == 'is-property-of') 
    w = 0.0 
    for p1 in properties(node1)[:k]: 
        for p2 in properties(node2)[:k]: 
            p = g.shortest_path(p1, p2, heuristic=h) 
            w += 1.0 / (p is None and 1e10 or len(p)) 
    return w / k 

We can then use similarity() to implement a one-versus-all search:

def nearest_neighbors(node, candidates=[], k=3): 
    w = lambda n: similarity(node, n, k) 
    return sorted(candidates, key=w, reverse=True) 

"What are creepy-looking animals?" For a given concept (e.g., creepy) and a list of candidates (e.g., animals), nearest_neighbors() yields the candidates with the highest similarity (the creepiest animals). In this particular example, it will suggest animals such as octopus, bat, owl, tick, spider, crow, ... No fluffy bunnies or frolicking ponies there!

print nearest_neighbors(g['creepy'], field(g['animal'])) 

Octopus has a direct creepy is-property-of octopus relation in the semantic network, so it is the obvious winner. However, things get more interesting when we look at the suggested bat. There is no creepy property for the bat concept. Instead, it is annotated with a black property and other relations to cave, evil, night and radar. It is associated to creepy by inference. More specifically, the model judges that the bat is a dark thing; and that dark is pretty creepy. Now where does dark come from? The direct relations of bat lead further to other concepts such as Darth Vader (via black and evil), dark, dangerous, pessimistic, airplane, sky, and so on. All of these concepts together make up the bat halo. Commonsense halo is explained in Chalmers, French and Hofstadter (1991), which argues the flexibility of human high-level perception – where objects and situations can be comprehended in many different ways depending on the context. The work includes an interesting quote by the late nineteenth century philosopher William James:

There is no property ABSOLUTELY essential to one thing. The same property which figures as the essence of a thing on one occasion becomes a very inessential feature upon another. Now that I am writing, it is essential that I conceive my paper as a surface for inscription. […] But if I wished to light a fire, and no other materials were by, the essential way of conceiving the paper would be as a combustible material. […] The essence of a thing is that one of its properties which is so important for my interests that in comparison with it I may neglect the rest. […] The properties which are important vary from man to man and from hour to hour. […] Many objects of daily use—as paper, ink, butter, overcoat—have properties of such constant unwavering importance, and have such stereotyped names, that we end by believing that to conceive them in those ways is to conceive them in the only true way. Those are no truer ways of conceiving them than any others; there are only more frequently serviceable ways to us.

The bat halo is a flexible representation of the concept bat: something dangerous, flying in the sky, reminiscent of a character named Darth Vader, associated with pessimistic things, resembling an airplane, and so on. The halo includes many latent properties, none of which are very merry: bad, black, brown, dark, deep, evil, negative, sad, and so on. The most salient ones measured by betweenness (i.e., amount of traffic passing through) are black, evil and dark. They are a kind of conceptual glue that the model will use to reason about bats. For k=3, it will measure the distance of these three to creepy using Dijkstra’s shortest path algorithm. The shorter paths are preferred, imitating the same cognitive bias in human intuition. The total "nearness" score is an indicator of the bat's creepiness. This approach will yield many possible solutions (i.e., divergent thinking) besides bat. As pointed out by Hofstadter, "making variations on a theme is really the crux of creativity". We can demonstrate the soundness of the approach by performing a search for happy animals instead of creepy animals. This will yield animals such as grasshopper, puppy, dog, chameleon, dolphin, kitten, and so on. These are certainly distinct from the creepy ones (we can argue about the chameleon).

The concept halo is important in another regard: computational tractability. It is intractable to calculate betweenness centrality for all concepts in large semantic networks as a whole: O(nm) for n concepts and m relations. This would be the equivalent of "seeing" your mind as a whole.

 


Brussels, the toad

As a thought experiment, suppose we want to create an advertising campaign to promote Brussels, the capital of the European Union. How can the model pick, for example, a striking image or photograph? We want something a little bit more thought-provoking than retrieving brussels.jpg from the Web. In the words of Veale, Feyaerts & Forceville: we want something that "compresses multiple meanings into a single form". Using the nearest_neighbors() function, we can shift the context of one concept to another concept as an exercise in combinatorial creativity. Unfortunately, perception has no Brussels concept. But we can annotate the semantic network by mining the Web with the tools in Pattern:

from pattern.web import Google, plaintext 
from pattern.search import search 

def learn(concept): 
    q = 'I think %s is *' % concept 
    p = [] 
    g = Google(language='en') 
    for i in range(10): 
        for result in g.search(q, start=i, cached=True): 
            m = plaintext(result.description) 
            m = search(q, m) # use * as wildcard 
            if m: 
                p.append(m[0][-1].string) 
    return [w for w in p if w in PROPERTIES] 

The learn() function returns a list of known properties for a given concept, mined from Google’s search engine with an "I think * is *" query. This is adapted from a technique for finding similes (as * as *) described by Veale & Hao (2007). In this particular instance, the results are: expensive, great (2x), green and proud. We update the semantic network on the fly:

for p in learn('Brussels'): 
    g.add_edge(p, 'Brussels', type='is-property-of') 

Now we can do:

print nearest_neighbors(g['Brussels'], field(g['animal'])) 

The top three nearest neighbors yields stag, frog and toad, where toad is our personal favorite. The figure below shows the subnet of properties that connect Brussels to toad. The shortest paths that connect them include: proudconfidentcalm and greatpleasantlazyslow.
 


Subnet of properties that connect Brussels to a toad.
The shortest path is Brussels → proud → confident → calm → toad
 

Smiling green toad. Photography © Sarah Crites. 
 

Let’s try another one with comparisons to persons:

print nearest_neighbors('Brussels', field('person', 2, 1)) 

We tweaked the parameters of field() to exclude general concepts such as brother and engineer. The nearest neighbors then yield Abraham Lincoln, Al Capone and Jerry Springer. The path to Abraham Lincoln is short and strong: through proud as well as great. The shortest path to Al Capone is expensivedrugdangerous. The shortest path to Jerry Springer switches tone: proudgoodevilcreepy. Let’s avoid a lawsuit and stick with an image of a toad. Hopefully the EU committee funding our marketing campaign has a sense of humor.

 


Novelty assessment

Creative ideas are novel as well as appropriate (Sternberg, 1999). One approach to measure the novelty of the model's suggestions is to count the number of web pages that mention each suggestion. It follows that suggestions that are less often mentioned are more novel.

Brussels + stag yields 25,000 results on Google. Brussels + toad yields 26,000 and Brussels + frog yields 125,000. By comparison, Brussels + waffles yields 1,700,000 and Brussels + sprouts yields 8,100,000. Since frogs score about 5x more results than stags and toads, we should probably discard the analogy as too common. In the sense of Boden’s distinction between H-creative and P-creative ideas (historical ↔ personal), all solutions are P-creative since no solution scores 0 (i.e., historically novel). See Veale, Seco & Hayes (2004) on compound terms for further discussion.

from pattern.web import Google 

def novelty(ideas=[]): 
    candidates = [Google().search(idea) for idea in ideas] 
    candidates = sorted(candidates, key=lambda results: results.total) 
    candidates = [(results.query, results.total) for results in candidates] 
    return candidates 

 print novelty(['Brussels stag', 'Brussels frog', 'Brussels toad']) 

Assessing appropriateness is a much harder task. For example, in terms of a scientific innovation, appropriateness pertains to performance, production cost, scalability, undesired side effects, and so on. Entire fields such as process management, risk management and workflow optimization have been devoted to such tasks. In terms of an artistic idea, the solution is often formulated to solve a wicked problem for which there are many possible solutions. In this case, appropriateness is usually assessed by peers. The model has no feedback loop to self-evaluate how and why it evaluated that Brussels has something in common with stags, frogs and toads.

 


Biased search

As noted, it is not hard to adapt the similarity() function to simulate other approaches besides the featural approach. For example, we could introduce cognitive bias by diverting the paths between properties via a fixed set of concepts. A fixation. Some of the results will be irrational now but that is what we want of course. The following lines of code compute p in the similarity() function with a fixed deviation via the sadconcept, perhaps not unlike a depression:

p  = g.shortest_path(p1, p2, heuristic=h) 
p += g.shortest_path(p1, g['sad'], heuristic=h) 
p += g.shortest_path(p2, g['sad'], heuristic=h) 

A search for creepy animals then yields grizzly, wolf, bat, raven and mole. A search for happy animals yields puppy, grasshopper, seal, reindeer, wolf, and oddly, meat. The preferred colors for a rocket are black and blue. Some of the original results still bubble up, but with a gloomy tone it seems. For Brussels it yields mockingbird.

Whether or not this is how cognitive bias really works in the human mind is debatable; in fact it is debatable that this is how the mind works at all.

 


Network visualization

To answer our initial problem, what colors does the system suggest for a rocket? 

print nearest_neighbors(g['rocket'], field(g['color'])) 

It yields yellow and red: warm, energetic colors. 

The functions in the pattern.graph module are identical to those in the graph module in NodeBox for OpenGL. We can combine the two implementations to visualize the network, using a force-directed algorithm to place the nodes on a 2D canvas. The figure below shows a visualization of the rocket concept halo: 



Visualization of the
rocket halo in NodeBox for OpenGL, with highlighted properties.
  

In Python code (simplified implementation): 

from nodebox.graphics import * 
from nodebox.graphics.physics import Graph as NodeBoxGraph 

g1 = g.copy(nodes=halo(g['rocket'])) 
g2 = NodeBoxGraph() 
for e in g1.edges: 
    g2.add_edge(e.node1.id, e.node2.id) 

def draw(canvas): 
    canvas.clear() 
    translate(canvas.width / 2, canvas.height / 2) 
    g2.update() 
    g2.draw() 

canvas.draw = draw 
canvas.run()

 


Discussion

When perception yields a clever solution, is it inherently creative or does it only appear to be so? The idea of a logo of a stag as "the proud flagship to represent the EU capital" is certainly promising, but this rendition is our own interpretation, not something the system came up with. The reason that some of the solutions seem so fitting is because our mind will automatically imagine the story between the input and the output. This tendency to see meaningful relations (e.g., narrative) in meaningless noise is caused by the priming effect, where the mind is prepared to interpret stimuli according to an expected model (Shermer, 2008).

Nonetheless, given that you had the same limited amount of knowledge to work with, a dull personality and a single thinking style, you might not be able to outperform perception. But unlike the real you, the model does not have a conscious feedback loop to reflect on big creative ideas, nor the flexibility to adopt different thinking styles besides the feature approach, and neither is it intrinsically motivated to do so.

These shortcomings pertain to an inability to evaluate and adapt. Knowledge, in the form of new concepts and relations in the semantic network, must be supplied by human annotators, either by hand or using the learn() function as discussed in the case study. We can refine the learn() function into an unsupervised, bootstrapped learning mechanism. If "I think Brussels is *" yields great, the search could then continue with "I think * is great", and so on. We can also refine the search heuristics to incorporate more search paths between concepts. In both cases the question of evaluation is raised. What is useful new knowledge and what is not? What are interesting new search paths, and which are not?

 


References

  1. Balota, D. A., & Lorch, R. F. (1986). Depth of automatic spreading activation: mediated priming effects in pronunciation but not in lexical decision.
  2. Boden, M. (2003). The Creative Mind: Myths and Mechanisms.
  3. Brandes, U. (2001). A faster algorithm for betweenness centrality.
  4. Brinton, L. (2000). The structure of modern English: a linguistic introduction.
  5. Buchanan, R. (1992). Wicked problems in design thinking.
  6. Chalmers, D., French, R., & Hofstadter, D. (1991). High-level perception, representation, and analogy: a critique of artificial intelligence methodology.
  7. Collins, A., & Loftus, E. (1975). A spreading-activation theory of semantic processing.
  8. De Smedt, T., De Bleser, F., et al. (2013). Gravital: natural language processing for computer graphics.
  9. Dijkstra, E. (1959). A note on two problems in connexion with graphs.
  10. Gilovich, T., Griffin, D., & Kahneman, D. (2002). Heuristics and Biases: The Psychology of Intuitive Judgment.
  11. Hellesoy, A., & Hoover, D. (2006). Graph JavaScript framework version 0.0.1.
  12. Hofstadter, D. R. (1985). Metamagical Themas: Questing for the Essence of Mind and Pattern.
  13. Jung-Beeman, M., Bowden, et al. (2004). Neural activity when people solve verbal problems with insight.
  14. Koestler, A. (1964). The Act of Creation.
  15. Lakoff, G., & Johnson, M. (1980). Metaphors We Live By.
  16. Mednick, S. A. (1962). The associative basis of the creative process.
  17. Norvig, P. (1987). Inference in text understanding.
  18. Osborn, A. F. (1963). Applied Imagination.
  19. Quillian, M. (1968). Semantic memory.
  20. Rittel, H. W. J., & Webber, M. M. (1973). Dilemmas in a general theory of planning.
  21. Schank, R., & Abelson, R. (1977). Scripts, Plans, Goals, and Understanding.
  22. Schilling, M.A., (2005). A “small world” network model of cognitive insight.
  23. Tversky, A. (1977). Features of similarity.
  24. Shermer, M. (2008). Patternicity: finding meaningful patterns in meaningless noise.
  25. Sternberg, R. J., & Lubart, T. I. (1999). The concept of creativity: prospects and paradigms.
  26. Veale, T., & Hao, Y. (2007). Learning to understand figurative language: from similes to metaphors to irony.
  27. Veale, T., Seco, N., & Hayes, J. (2004). Creative discovery in lexical ontologies.