Showing posts with label abstraction. Show all posts
Showing posts with label abstraction. Show all posts

Thursday, March 11, 2010

Some Parts have a (sex) life of their own

In heeding my earlier post which advocates that "wholes" be analyzed and modeled, rather than just their "parts", there is the danger of swinging to the opposite extreme of not considering parts as "individuals".  After all, if one can model an entire Car as having a paintColor property, with a simple value of Red, then there is no need to model Paint as an entity on its own, much less PaintMolecule or Atom.

When the parts of X are considered "stuff" instead of "things" (e.g. paint versus wheels), or, when their abstraction level is so low that they are interchangeable (like WHICH carbon atoms are in the paint), it is usually concluded that they are outside the scope of X’s model because they make no difference at the level of the whole X.  And certainly, if a whole has a property, there is no need to have each part redundantly carry the same property just to parrot the value of the whole.  For example, the case study in that earlier post chronicled the “BigBank” database, in which the record for each obligation in a facility redundantly recorded the same single “facility grade”, even though they were always graded as a whole facility.

The problem, of course, is knowing which parts are relevant at the level of the whole (i.e. the granularity of the model). In recent science news, an example of this quandary has arisen which illustrates how parts that were considered “stuff” are really individual things. It turns out that the rare chicken who grows up half-male and half-female does so in a way that is different from humans and other mammals.

Until now, it’s been assumed that body parts (and hence their constituent cells) always grew up male or female because external hormones told them to, and told them to as a whole.  The Nature paper announced the discovery that each cell in a half-and-half chicken has maleness or femaleness as an intrinsic property from birth. In mammals, if you transplant a formerly “male” cell into a “female” organ, it will start working as a female, whereas in chickens it will keep acting male.  To switch metaphors: It turns out that the car wasn’t painted red and green after the fact; each car part was already red or green ever since its manufacture, and each is resistant to change. So, cells/parts have to be modeled individually if you are building chickens/cars.

Of course, if you are only collecting (and not building) cars, you might still think of color as a property of the car as a whole. But here is the sticky part…a painful situation occurs when the car collector later needs spare parts, but their inventory database was never designed to track part colors.  I have often encountered this situation in corporate/enterprise systems that are too brittle because their data models were overly simplified.  Sometimes the problem is that the designs were based on short term goals. [This mistake is exacerbated by some development “methodologies” that advocate only designing for today’s needs.] Other times, problems result from making quick assumptions about the nature of things being modeled rather than taking a deep look (i.e. using the fruits of Philosophy’s “best practices” as developed over 2500 years). The case study ahead illustrates this scenario.

This case study comes from another BigBank project where there was an enterprise-wide project to revamp systems to use a single standard ID number for each customer.  Their (initial) proposal was published after over a year of analysis and requirements gathering. But, from the very beginning, a Customer was intuitively defined as synonymous with “legal entity”, where a legal entity has only one government Tax ID (e.g. SSN, EIN).

Because only the whole was modeled, all the other systems that needed parts granularity balked, and the project had to take another year to rework its proposal.  Many systems and business processes needed to work with individual stores, branches and managers, and they depended on having a separate “customer ID” for each location.  While many companies have separate corporations (i.e. tax IDs) for each branch, some very large companies (e.g. Walmart) do not.  Because many systems and business processes required a single bank officer to service a single customer, it would have forced thousands of branches onto a single virtual desktop.  It also turned out that, while cities have a single tax ID, some parts (e.g. the City of Atlanta) are not legally liable for the debts of other parts (e.g. the Atlanta airport) even though they all share the same single tax ID.

So, without sufficient analysis, things that seem like wholes, can really be collections of parts.

Tuesday, September 15, 2009

Why did the Action Philosopher cross the road?

“Why” is such an ambiguous question; it asks about an event…
  1. what were the “causes” (i.e. the physical producers of effects)
  2. 
what were the “actions” (i.e. who did what)

  3. what were the “reasons” (i.e. thoughts, motivations by someone that led to their (in)actions).

And to make things worse, each of those categories of questions can be answered at many different levels of abstraction. “Why did Y die?” could be answered with:
  1. causes: “Y’s car crashed” or more specifically “Y’s brakes failed”
  2. actions: “X sabotaged Y’s car” or more specifically “X cut the brake line”
  3. reasons: “X wanted revenge” or more specifically “X wanted Y dead”.
And still worse, each of those categories exist in a chain such that each answer to “why” produces a new “why” question. Each cause has its own cause, actions occur in ordered sequences, and reasons are triggered by previous events. So, “why did X want revenge?” because “Y intentionally ruined X’s wedding”, “well WHY did Y do that?”, and so on. “What is happening” is an equally ambiguous question because it can also be answered in terms of causes or actions or reasons.

The Chicken crossing the road joke is so old, with so many new punch lines, that people sometimes don’t get the original joke anymore. It, of course, is that the answer “to get to the other side” is too much of a HOW rather than a WHAT (i.e. confusing proximate and ultimate goals). In the Philosophy of Action, which seeks to differentiate things done on purpose from things that merely happen, many philosophers have difficulty in separating what a person is doing from how they are going about doing it (not to mention, where their concept of “intention” fits in). Distinguishing what from how is so central to writing specifications, programs & documentation, that we Programmers should have something useful to pass along to Philosophers. I would teach them about our knowledge of: levels of abstraction, the difference between top-down and bottom-up views of the world, and the difference between the “intention” of the logic versus an instruction trace. Not that programmer’s have no problems in this regard…

Top Down: Good Grief! Why don’t you move this code out into subroutines? There are fifty pages of code in one switch statement here! I can’t see the forest for the trees.

Bottom Up: Good Grief! How can I tell what the program is doing when it is ten levels deep in function calls!
Top Down: At the very least, put some comments in here to say what the program is doing.

Bottom Up: I don’t believe in comments because the source code tells you exactly what the program is doing.

Top Down: Ok, so what does this part of your program do?

Bottom Up: Well, “i” is set to zero, and then it gets incremented each time through this loop here, and…

Top Down: No, really. Put comments in English telling what the program was supposed to be doing.

Bottom Up: Ok…. ++i; /* Increment i */



Events & Causes vs Actions & Reasons

“What is left over if I subtract the fact that my arm goes up from the fact that I raise my arm?" - Ludwig Wittgenstein, Philosophical Investigations §621
Human Agency, Intention, Actions, and Events are topics in Philosophy of Action and Philosophy of Mind. Events are simply “things that happen”[2] in a chain of causes and effects. Agency is a philosophical term for what programmers call “a thread of control”. Human Agency is the capacity of human beings to make choices and act upon them. In Action Theory, if an AGENT A has the DESIRE for X plus the BELIEF that doing Y will result in X, then A will have the INTENTION of doing the ACTION Y. If A actually does Y, then that desire and belief should be considered CAUSES of the EVENT of Y happening (…or not: “There has been a notable or notorious debate about whether the agent's reasons in acting are causes of the action”[3]). Unless specifically noted as unintentional, actions are only those that an agent does intentionally, so falling off a cliff would not be an “action” but jumping off would. Actions usually involve “bodily movements” that effectively translate mental intentions into physical events. (“Actions are bodily movements that are caused and rationalized by an agent’s desire for an end and a belief that moving her body in the relevant way will bring that end about.”[5]) Further, there is a certain moral component to human (in)actions that doesn’t apply otherwise. One can ask “should this have happened” about human actions (say, not pre-evacuating New Orleans), which would make no sense for events & actions that involve no human decisions (e.g. Katrina hits New Orleans, or, the spider killed the fly). Finally, in the Identity Theory of Mind[4], it is held that mental states, processes, and events (like desiring to eat ice cream) are mirrored by brain states, processes, and physical or physiological events (like this and that neuron firing).

Background: philosophers/metaphysicians are interested in figuring out what is “really real” versus just a story our mind made up in trying to interpret all those real-world inputs we get from our senses. They have decided that a way to prove that a thing is “real” is to show that it can affect an event happening or not: “a test of the reality of a property is that it can be causally efficacious”[6]. So, that is why there is so much interest in the relationship between actions/reasons/intentions and the scientifically measurable physical events/causes. If one can’t show how the intention to perform the action of eating an ice cream cone somehow translates into a synapse causing a tongue muscle contraction event, then maybe actions and intentions aren’t really real.

So! All settled then! Well no. Here is just a sampling of technical disagreements between philosophers:
  • Is the “action” of moving a body part the same as the actual movement of the body part? Or is the action just the “intention” bit.
  • Contrary to the Identity Theory of Mind, some say[5] that you can’t map intentions onto brain states because intentions aren’t events, so you won’t find any corresponding physical events to map to. That’s why, explanations in everyday conversation, even by pro-ITOM philosophers and scientists, are in terms of intentions (“she crossed the road to catch the bus”) rather than mental and brain states. Still others say that “intention” isn’t real, it is only a story we tell to explain the world.
  • Some say “that which causes an action constitutes the agent’s reason for it.”, others say that you can’t explain the “reason” why somebody did something by just looking at what “caused” it.[5]
  • Causal Fundamentalism says that everything can be explained at the “physics” level of causes and effects, others say no.[5]
  • Some say actions are a subclass of events; others say actions are a relationship between an agent and an event, i.e. actions are instances of the relation (agent, “bringing about”, event). [Programmers think: difference between “class Action extends Event” versus “create table BringingAbout(ActionID,AgentFK,EventFK)”]
So, does the action of “turning on a light” include “the light illuminating”, or does it stop at “flipping the switch”, or at “the hand movements that flip the switch”, or at “trying to move the hand”? Does it include the firing of the neurons? the muscles contractions? the moving of the bones? Are they all separate actions, or not actions at all? Are they the only actions with no overarching “flip the switch” action?

As I wrote about the mind/body problem, I think we have a levels of abstraction problem here.

Programmers understand that systems are built in layers where each layer exposes WHAT it can do on top, hiding the HOW it does it underneath. The how of one layer uses the what of the layers below it. There are layers on top of layers, and there are layers within layers. Computer software forms a layer on top of computer hardware, but there are multiple layers within each. Within software there are layers for programs on top of High Order Languages on top of Assembly language. Within hardware there are layers for processors & memory on top of logic circuits & amplifiers on top of transistors & resistors on top of literally layers of silicon dioxide & gallium arsenide. Some of these layers are so complete and versatile that they form their own independent paradigm such that events can be completely described at their level with no reference to layers above or below it.

Another way to look at levels of abstraction is in the way that the same series of events can be interpreted in a hierarchy of meaning. For example, this text has meaning as a series of sentences, but it can also be interpreted as just a series of words, which are just a series of letters, which are just a series of ASCII codes, which are just a series of hex digits, which are just a series of binary digits, which are just a series of alterations between zero and five volts on a chip. Same universe but simultaneous multiple levels of interpretation into events.

The WHAT defines the intention to do some action, and The HOW is the planned (in advance or on the fly) set of more detailed actions to accomplish it. One can describe and explain the action at any level, but confusion occurs when jumping around from one level of abstraction to another. This is a problem when programmers or philosophers do it. Intermixing instructions at one level with more detailed instructions from lower levels makes it hard to follow the logic at either level. Non-programmers can understand this by imagining a cake recipe that goes into the instructions for growing wheat in the section that “desires” a cup of flour.

SO, human agency is equivalent to the “top level of abstraction” that is deciding WHAT ultimate goal state is desired, and it entails all the lower levels. And like a software process (i.e. agent), there is a “thread of control” that threads through the call stack, traversing down through the levels of HOW, returning back up through layers of WHAT.

Intention

What is it for a person to “will” or “intend” an action? Does the intention to raise one’s arm manifest itself as a brain state that can be seen in some scanner, as distinct from the actual activity of raising that arm? Jennifer Hornsby rejects “the physicist’s Fundamentalism”, because it lacks “intentionality”[5]. As described earlier, each level of abstraction can simultaneously tell the story in its own terms, BUT, that doesn’t mean being able to see “intention” at any level just from looking at “what happened”. In the first place, it is hard to translate upward in the abstraction layer cake. Secondly, looking only at the events that occur leaves out the intentional logic paths not taken.

Even though programmers know that there is “intention” in programs (because that’s how we write them!), in programs written by someone else it is often difficult to divine what it is. To translate back up to the “WHAT was intended” from the “HOW it was implemented” is so hard that we tell programmers to write it explicitly in comments in the code. When faced with fixing a flawed program whose intention isn’t clear, programmers will prefer to rewrite it from scratch rather than trying to figure out what it was doing.

Programmers know that when analyzing an ICE instruction trace (think flight data recorder for programs), it will not show all the “intention” in a program because it will not show the paths in the program logic that were not taken. You might infer that a decision was being made by the code when it executed certain test and branch instructions, but you won’t see the “road not travelled”. That’s why in debuggers it is crucial to have access to the source code to see the complete logic, whether it was executed or not, otherwise one could not diagnose and correct any incorrect translations of “intention” at one level of abstraction into a “plan of action” at the next lower level.

Also, with regard to looking for intention in brain (or computer memory) states, it is in the program logic, not the “state data” nor the instruction trace. BUT, intentions are not mystical nor abstract, they are physically embodied somewhere. With computer programs, it is in the encoded logic which sits side by side with state data in memory hardware. Because, at the right level of abstraction, the encoded intentional logic IS just data.

Now, like action theory rules, workaday computer programs lay out the “intentions” in designed plans of explicit rational language. In artificial intelligence programs, the intentions are often implied via weighted scoring of alternative actions. And, the brain may act more like the ant colony example of emergence. The “purposeful” behavior of the colony as a whole “emerges” out of the actions of all the individual ants who presumably have no clue about the “intentions” of the colony. So brain/colony intentions may not be “designed” as much as “evolved”. On the other hand, programmers are painfully aware of inexplicable behavior by programs that they designed. And, lest non-programmers assume that rationally designed program behavior can’t mindlessly evolve, there are many times when bugs get fixed by making a local logic change with no idea of the global consequences; and if that band-aid causes a new bug over there, then another band-aid is placed over there, and so on, until the behavior has evolved just enough to pass inspection. However, in all those cases, while the intentions at one level may be hard to map to those at another, they are, in fact, all there at once.

SO, why DID the chicken cross the road? Well, because the muscles in the left leg contracted causing it to move forward, then the muscles in the right leg…


[Ed. Note - 12/11/12: as per my disclaimers, once I start looking for my epiphanies on the net, I find them. E.G. in this case, see "Aristotle's Four Causes". Congrats Bruce, your musings on the various meanings of "why" were done better 2400 years ago...read more!]

[1] Philosophy Bites podcast on agency

http://philosophybites.com/2008/06/jennifer-hornsb.html
[2] Casati, Roberto, Varzi, Achille, "Events", The Stanford Encyclopedia of Philosophy (Fall 2008 Edition)

http://plato.stanford.edu/archives/fall2008/entries/events/
[3] Wilson, George, "Action", The Stanford Encyclopedia of Philosophy (Fall 2009 Edition)

http://plato.stanford.edu/archives/fall2009/entries/action/
[4] Smart, J. J. C., "The Identity Theory of Mind", The Stanford Encyclopedia of Philosophy (Fall 2008 Edition)

http://plato.stanford.edu/archives/fall2008/entries/mind-identity/
[5] Jennifer Hornsby, Agency and Actions, Cambridge Univ Press, 2004

http://eprints.bbk.ac.uk/95/
[6] Jacob, Pierre, "Intentionality", The Stanford Encyclopedia of Philosophy (Fall 2008 Edition)

http://plato.stanford.edu/archives/fall2008/entries/intentionality/




Wednesday, September 2, 2009

Programmer: What Mind/Body Problem?

While my general project these days is trying to teach programmers the many things they can learn from Philosophy, I am once again struck by how many philosophers get confused by things that programmers understand quite well. In today’s particular case, it is while reading "Which Physical Thing Am I?"[1], and once again, it is related to the "mind/body problem". That essay ends “if this philosophic hypothesis seems implausible to you, you try to formulate one that is less implausible.” Well, my reply is "let me teach you about levels of abstraction and RAID drives”.

Mind/Body Problem

Thinkers over time have recognized that a person remains the “same person” even though their body undergoes changes over time, even to the extent of losing parts; say, an arm, or a leg. In 1954, it was discovered that "98% of the atoms in the human body are renewed each year"[2]. This has led many to conclude that what makes a person a person, must be different and separate from their body. For some, this different thing is a "soul". For others, it is a "mind" or “consciousness”. In general, this is often called mind-body dualism.

Others have concluded that, because nothing exists outside of physical reality, the mind can't be different from the body, but since the body does change over time, there must therefore be some subset of the body (say, the brain) that is identical to the mind. Jews and Muslims believe[4] that there is a bone in the spine, called the "Luz", that doesn't decay, and from which the entire body will be rebuilt during resurrection. Dr. Roderick Chisholm, thinks that, while it probably isn't the Luz bone, it likely is something microscopic within the brain. In "Which Physical Thing Am I?"[1] he writes,

"I am literally identical with some proper part of this macroscopic body, some intact, nonsuccessive part that has been in this larger body all along."
[By "nonsuccessive", he means something that is NOT a series of different parts over time. By contrast, an army regiment is successive in that it can exist for hundreds of years even though no individual soldier does.]

Software/Hardware Non-problem

Now keep in mind that the Stanford Encyclopedia of Philosophy[3] describes Chisholm as "widely regarded as one of the most creative, productive, and influential American philosophers of the 20th Century", and that Chisholm published the above in 1989 (not 1889), and it is included in anthologies[1] as recently as 2008 (not 1908). It is not just ancient philosophers who get confused over this topic. What are they confusing that programmers know?

Programmers know that software (like the mind) runs on hardware (like the body), but it isn’t synonymous with the hardware. That doesn’t make software mystical or beyond physical reality; it is just at a higher level of abstraction. At that more abstract level, software exists as an information process whose data state at any given point in time is embodied in some set of physical components. But it would be the same software even if running on other equivalent hardware.

In fact, there are several layers of abstraction between your typical program and hardware, what with Java code compiled into virtual machine code, interpreted in a VM written in C code, that compiled to Intel assembly code, that assembled into
hexadecimal machine code,… And we haven’t even made the leap to electrons flowing through transistors yet! The point being that software doesn’t care which transistors, even though every i+=1; statement runs in lock step with some transistors somewhere doing something specific to implement them. If that flip-flop didn’t flop then that bit wouldn’t change, and that auto-increment instruction wouldn’t increment, and so on. But, a programmer understands that it isn’t the electrons running through the NAND gate that “makes” a program DO what does, any more than some x=0; statement makes a Square.draw() method DO what it does. They all happen simultaneously at different levels of abstraction.

RAID fights bugs

To Chisholm’s particular point that continuous personhood requires (at least some) continuous body bits, programmers know that the “life span” of any particular set of data, is not tied to any particular physical component. Information is independent of the media used to record, or embody, or carry a copy of, that information. A perfect example is a RAID device containing multiple disk drives. Data in a RAID is kept in multiple physical locations such that any particular location can be destroyed without losing the data. So, an arbitrary set of data (say, a file) can exist unchanged over time, even though the hardware storing it has completely changed. With a “hot swap” RAID, a system using that file would have no idea that a drive died, was removed, replaced with a new drive, and that new drive re-populated with data.

And, just like a mind’s constantly changing data set, that file’s contents on the RAID device can be constantly changing. And those constant data changes are totally independent of the constant drive changes that might be taking place inside the RAID.

The point here is not “the brain is a RAID drive”; the point is that a RAID drive is an existence proof that ongoing software processes do not require “intact, nonsuccessive” hardware. And the larger point is that Mind and Body can both be understood as simultaneous lock-step processes at different levels of abstraction in the same way that C++ method calls are in lock-step with CMOS chip voltage changes.

[1] Metaphysics, the big questions, 2nd Ed., 2008, chap 35
[2] Time Magazine, Oct 11, 1954 quoting Dr. Paul C. Aebersold of Oak Ridge
http://www.time.com/time/magazine/article/0,9171,936455,00.html
[3] http://plato.stanford.edu/entries/chisholm/
[4] http://en.wikipedia.org/wiki/Luz_%28bone%29




Saturday, October 7, 2006

Post Facto Polymorphism

Post Facto Polymorphism ®☺ is the Existential Programming technique of mapping an abstraction (defined after the fact of creating actual object instances or relational database entities or semantic network relations) to multiple preexisting ontologies (i.e. class/type definitions).

For example, suppose that there were several data sources that held data (specifically names) about "people", and these data sources were culturally specific. A typical European ontology/DB-schema might define 3 fields: firstName, middleName, lastName. A Native American oriented database might define a single Name field. An Asian database might have a familyName and a childName field. Yet another ethnic database encoded names into the European schema but understood that
firstName was the "family name" for its data rather than lastName. If we wish to consolidate these data sources and define (after the fact) a new abstraction to work with all of them, we can use the external abstraction technique to adapt each of these apples and oranges to all be "fruit".

An AbstractName interface could be defined, and adapters defined for each "concrete class" that implement the mapping between that class' name-related properties and the
properties of AbstractName. By having objects be "existential", thus allowing mixin adapter code to be dynamically added, the objects can all be accessed via the getFamilyName() and getTheNamePeopleCallMe() methods defined by AbstractName.

Of course, all this support for "cleaning up" data via external abstraction should not lessen the pressure to clean up the source data as much as possible (by which I mean cleaning up the schema and entity definitions more than the data itself). Otherwise, multiple "bad" data sources, each having their own classes/interfaces/source-of-record IDs/"package IDs", would need to be specified when referencing data in order to disambiguate which data source is desired. By cleaning up the schemas (to make the semantics more well-defined), fewer explicit "package ID" references are required
, and one's code is much simpler/cleaner.

External Abstractions, Existential Classes, Object Views

Traditionally, object oriented modeling proceeds "top down" in that classes/interfaces are defined first and then instances (i.e. "objects") are created. Essence Precedes Existence. The objects consist of the class-defined attribute set, the whole class-defined attribute set, and nothing but the class-defined attribute set!

In Existential Programming, the developer can define "bottom up" classes/interfaces where, after the fact, attributes can be chosen from existing ones, or new "computed" attributes can be added. Existence Precedes Essence. This is very similar to the database concept of "view" where some subset of columns can be dealt with as if they were their own table/entity. These views can also add "computed" or "joined" columns thus supporting the philosophy that there is a fine (or non-existent) line between "behavior" and "data". They are all just properties, and it is inside the black box that the details exist of what was required to get or set that property (using Java-speak).

A difference between this object view idea and normal interfaces is that the interface declaring a method has to be defined before the class that implements it is defined, which in turn is before an object (based on that class definition) is created. With a view, an object could be "cast" to some defined-after-object-creation interface, as long as that object had the methods/properties that the view expected. Otherwise, potentially a cast-exception could be thrown (or, it could just let you work with any methods that *did* match). Of course, with Existential Programming, all "interfaces" and "classes" are the same as "views". There is no single "real" version of an object/entity with other versions just "views". This is different from database views where down deep there IS a "real" table (or several if the view was really a "join"). With Existential Programming's strategy of using EAV structure for persistence, all entity definitions / classes / interfaces are "views".

This sort of thing is done with dynamic languages like JavaScript and is called "duck typing". This name reflects 2 puns simultaneously:
  1. "quacks-like-a-duck" typing (vs strong or weak typing)
  2. duct taping (which is what all weakly typed programming is in the opinion of many)
In the same way database views can use logic to calculate attributes and join tables, existential classes/ontologies should be able to map/calculate each attribute via references to the attributes in other classes/ontologies. These ideas resonate with the "rules" in logic-programming languages like Prolog.

External Abstraction ®☺

A related idea I've had is that of the "external abstraction" where, instead of merely views, whole hierarchies of super-classes, subclasses, and interfaces are defined after the fact. ["Internal" abstractions would be those normal OO abstractions where the super-classes and interfaces supported by an object were those that were defined when the object instance was created (i.e. its essence).]

The point of "external" abstractions is that someone "external" (i.e. other than the ontology creator and object instantiator) can decide (after an object has been created) that some aspect of the object is overly specific to one point of view and needs to support other points of view. For example, the "name" attribute of "person" classes is often broken into first name, middle name, last name which is very culturally biased. So, support needs to be added for other cultures where "last name" is not synonymous with "family name", and there is no "Christian name", and not everyone has three names.
Is Dances with Wolves' middle name "with"?

Normally, if one were refactoring that class hierarchy to better handle names, one would convert the 3 string fields representing the name into a reference to a new Name interface and define classes that implement various permutations of name. The interface could have methods like getFamilyName() which determined the value based on the particular cultural variant name class instantiated. This is all nice when one can do this beforehand such that is it all compiled and ready for the code to use before the person object is instantiated. With External Abstraction, the developer can do this refactoring and apply it to an entity that has already been created and exists as an object or persisted to some data store. By adding in a newly created "
mixin" interface/class to the preexisting object, the 3 name fields can be reinterpreted and mapped to other ontologies supporting other cultures.