Prolog returning false for sudoku solver - prolog

:-use_module(library(clpfd)).
solve(X,Board):-
Board=X,
Board =
[A1,A2,A3,A4,A5,A6,A7,A8,A9,
B1,B2,B3,B4,B5,B6,B7,B8,B9,
C1,C2,C3,C4,C5,C6,C7,C8,C9,
D1,D2,D3,D4,D5,D6,D7,D8,D9,
E1,E2,E3,E4,E5,E6,E7,E8,E9,
F1,F2,F3,F4,F5,F6,F7,F8,F9,
G1,G2,G3,G4,G5,G6,G7,G8,G9,
H1,H2,H3,H4,H5,H6,H7,H8,H9,
I1,I2,I3,I4,I5,I6,I7,I8,I9],
Board ins 1..9,
label(Board),
%rows on the board
all_different([A1,A2,A3,A4,A5,A6,A7,A8,A9]),
all_different([B1,B2,B3,B4,B5,B6,B7,B8,B9]),
all_different([C1,C2,C3,C4,C5,C6,C7,C8,C9]),
all_different([D1,D2,D3,D4,D5,D6,D7,D8,D9]),
all_different([E1,E2,E3,E4,E5,E6,E7,E8,E9]),
all_different([F1,F2,F3,F4,F5,F6,F7,F8,F9]),
all_different([G1,G2,G3,G4,G5,G6,G7,G8,G9]),
all_different([H1,H2,H3,H4,H5,H6,H7,H8,H9]),
all_different([I1,I2,I3,I4,I5,I6,I7,I8,I9]),
%columns on the board
all_different([A1,B1,C1,D1,E1,F1,G1,H1,I1]),
all_different([A2,B2,C2,D2,E2,F2,G2,H2,I2]),
all_different([A3,B3,C3,D3,E3,F3,G3,H3,I3]),
all_different([A4,B4,C4,D4,E4,F4,G4,H4,I4]),
all_different([A5,B5,C5,D5,E5,F5,G5,H5,I5]),
all_different([A6,B6,C6,D6,E6,F6,G6,H6,I6]),
all_different([A7,B7,C7,D7,E7,F7,G7,H7,I7]),
all_different([A8,B8,C8,D8,E8,F8,G8,H8,I8]),
all_different([A9,B9,C9,D9,E9,F9,G9,H9,I9]),
%different boxes
all_different([A1,A2,A3,B1,B2,B3,C1,C2,C3]),
all_different([A4,A5,A6,B4,B5,B6,C4,C5,C6]),
all_different([A7,A8,A9,B7,B8,B9,C7,C8,C9]),
all_different([D1,D2,D3,E1,E2,E3,F1,F2,F3]),
all_different([D4,D5,D6,E4,E5,E6,F4,F5,F6]),
all_different([D7,D8,D9,E7,E8,E9,F7,F8,F9]),
all_different([G1,G2,G3,H1,H2,H3,I1,I2,I3]),
all_different([G4,G5,G6,H4,H5,H6,I4,I5,I6]),
all_different([G7,G8,G9,H7,H8,H9,I7,I8,I9]).
37 ?- solve(Solution,[,,,,,,,,,,,,,,3,,8,5,,,1,,2,,,,,,,,5,,7,,,,,,,5,,7,,,,,,4,,,,1,,,,9,,,,,,,,5,,,,,,,7,3,,,2,,1,,,,,,,,,4,,,_,9]).
false.
Well, below there's a hyperlink of code to compare mine to, I compared it myself and apart from the fact that mine's 9x9 and his is 4x4 (and that I use ins instead of fd_domain) I can see no difference...My question is, might this be false because I'm using ins instead of fd_domain or is it something else that I can't see?
Some code which I compared my own to

Normally, label/1 it's called after all constraint posting. That's because it must, well, label each variable, i.e. enumerate remaining values after pruning. But your main problem it's that you're passing a wrong board, of 90 elements, instead of 81, as it should be.
I can show you with this weird 'query':
?- atomic_list_concat(L, ',', ',,,,,_,,,_,,,_,,,3,,8,5,,_,1,,2,,_,,,_,,,5,,7,,_,,,_,,5,,7,,,_,,,4,,,_,1,,,_,9,,,_,,,_,,5,,_,,,_,,7,3,,_,2,,1,,_,,,_,,,_,4,,,_,9'),findall(Y,(between(1,10,_),length(Y,9)),G), append(G,L),maplist(writeln,G).
[,,,,,_,,,_]
[,,_,,,3,,8,5]
[,_,1,,2,,_,,]
[_,,,5,,7,,_,]
[,_,,5,,7,,,_]
[,,4,,,_,1,,]
[_,9,,,_,,,_,]
[5,,_,,,_,,7,3]
[,_,2,,1,,_,,]
[_,,,_,4,,,_,9]
L = ['', '', '', '', '', '_', '', '', '_'|...],
G = [['', '', '', '', '', '_', '', ''|...], ['', '', '_', '', '', '3', ''|...], ['', '_', '1', '', '2', ''|...], ['_', '', '', '5', ''|...], ['', '_', '', '5'|...], ['', '', '4'|...], ['_', '9'|...], ['5'|...], [...|...]|...].
try to call your program in this way (just a sample, to show a proper fomatting):
?- solve([
/* 1,2,3,4,5,6,7,8,9 */
_,_,2,_,_,_,_,_,_,
1,_,_,_,8,_,_,_,_,
...
/* there must be 9 rows */
], X).

Related

prolog task solving using swi-prolog IDE

Given the attached knowledge base "students_courses.pl" containing students' grades in
some courses and courses' prerequisites, you are required to write a Prolog program
that solves the task explained below.
Get a list containing the sequence of courses that a student needs to take in order to
be able to take the target course. The query must only succeed if the student has
already taken and successfully passed a course that can directly or indirectly lead to
the target.
Examples:
?- remainingCourses(stud01, 'Advanced Algorithms', Courses).
Courses = ['OOP', 'Data Structures', 'Algorithms']
?- remainingCourses(stud07, 'Electronics 2', Courses).
false.
?- remainingCourses(stud02, 'Networks', Courses).
Courses = []
?- remainingCourses(stud05, 'Computer Architecture', Courses).
Courses = ['Electronics 2']
?- remainingCourses(stud08, 'Data Warehouses', Courses).
false.
given this file.pl:
student(stud01, 'Programming 1', 90).
student(stud01, 'Math 1', 78).
student(stud01, 'Statistics 1', 94).
student(stud01, 'Electronics 1', 81).
student(stud01, 'Management', 66).
student(stud01, 'English', 83).
student(stud02, 'OS 1', 65).
student(stud02, 'Math 1', 50).
student(stud02, 'Data Communication', 76).
student(stud03, 'OOP', 68).
student(stud04, 'Database', 59).
student(stud04, 'Math 3', 67).
student(stud05, 'Programming 1', 88).
student(stud05, 'Math 1', 75).
student(stud05, 'Statistics 1', 96).
student(stud05, 'Electronics 1', 89).
student(stud05, 'Management', 84).
student(stud06, 'Robotics', 62).
student(stud07, 'Programming 1', 50).
student(stud07, 'Math 2', 8).
student(stud07, 'Statistics 2', 70).
student(stud07, 'Electronics 1', 47).
student(stud08, 'OS 1', 71).
prerequisite('Programming 1', 'OOP').
prerequisite('OOP', 'OS 1').
prerequisite('OS 1', 'OS 2').
prerequisite('OOP', 'Data Structures').
prerequisite('Data Structures', 'Algorithms').
prerequisite('Algorithms', 'Advanced Algorithms').
prerequisite('Math 1', 'Math 2').
prerequisite('Math 2', 'Math 3').
prerequisite('Math 3', 'Math 4').
prerequisite('Statistics 1', 'Statistics 2').
prerequisite('Electronics 1', 'Electronics 2').
prerequisite('Electronics 2', 'Computer Architecture').
prerequisite('Computer Architecture', 'Microprocessors').
prerequisite('Data Communication', 'Networks').
prerequisite('Database', 'Data Warehouses').

Ruby array of countries stripe connect accepts?

Is there somewhere I can get this list of countries as a ruby array?
I'll need it for a form field e.g.
<%= f.label :country %><br>
<%= f.select :country, ['Australia', 'Austria', 'etc', 'etc'], required: true %>
I could type it up manually (which I'll probably do), but just wanted to check that I'm not reinventing the wheel (it may already exist somewhere)
Okay, so there it is. Note that Mexico's commented out
stripe_connect_countries = [
'Australia',
'Austria',
'Belgium',
'Bulgaria',
'Canada',
'Cyprus',
'Czech Republic',
'Denmark',
'Estonia',
'Finland',
'France',
'Germany',
'Greece',
'Hong Kong SAR China',
'Hungary',
'Ireland',
'Italy',
'Japan',
'Latvia',
'Lithuania',
'Luxembourg',
'Malta',
# 'Mexico',
'Netherlands',
'New Zealand',
'Norway',
'Poland',
'Portugal',
'Romania',
'Singapore',
'Slovakia',
'Slovenia',
'Spain',
'Sweden',
'Switzerland',
'United Kingdom',
'United States'
]
Also note, that the country argument to Stripe functions typically wants a two-character alphanumeric country code (such as 'US', 'EG', or 'GB'). Here is a full list of country codes
Since it turns out these countries are user-friendly, but Stripe functions require the 2 character codes, here's a useful function providing a hash mapping countries to codes (again, Mexico commented out)
def stripe_connect_countries
{'Australia': 'AU',
'Austria': 'AT',
'Belgium': 'BE',
'Bulgaria': 'BG',
'Canada': 'CA',
'Cyprus': 'CY',
'Czech Republic': 'CZ',
'Denmark': 'DK',
'Estonia': 'EE',
'Finland': 'FI',
'France': 'FR',
'Germany': 'DE',
'Greece': 'GR',
'Hong Kong SAR China': 'HK',
'Hungary': 'HU',
'Ireland': 'IE',
'Italy': 'IT',
'Japan': 'JP',
'Latvia': 'LV',
'Lithuania': 'LT',
'Luxembourg': 'LU',
'Malta': 'MT',
# 'Mexico': 'MX',
'Netherlands': 'NL',
'New Zealand': 'NZ',
'Norway': 'NO',
'Poland': 'PL',
'Portugal': 'PT',
'Romania': 'RO',
'Singapore': 'SG',
'Slovakia': 'SK',
'Slovenia': 'SI',
'Spain': 'ES',
'Sweden': 'SE',
'Switzerland': 'CH',
'United Kingdom': 'GB',
'United States': 'US'
}
end

how to put a char into a string with a condition

I'm very new in informatica and I would like to add a port with a expression which adds a char based on a condition.
example:
ports that are going to be checked:
Input:
a: T
b: T
c: F
output:
Result example: "110"
How I try to resolve it: I added an Expression Transformation
T stands for 1
F stands for 0
IIF(a= 'J', result||'1', IIF(b='J', result||'1' , IIF(c='J', result||'1',result||'0')))
is this correct? Or is there a better solution, that someone could suggest?
Please use below condition,
IIF(a = 'T', '1', IIF(a = 'F', 'O')) ||
IIF(b = 'T', '1', IIF(b = 'F', 'O')) ||
IIF(c = 'T', '1', IIF(c = 'F', 'O'))
Not sure why you are concatenating result, is it an input/ variable port? If so you can concatenate along with the above function itself as below,
IIF(a = 'T', result||'1', IIF(a = 'F', result||'O')) ||
IIF(b = 'T', result||'1', IIF(b = 'F', result||'O')) ||
IIF(c = 'T', result||'1', IIF(c = 'F', result||'O'))

Fill area above line in AmCharts

I'm plotting threshold violations. In some cases, thresholds are violated when the values are above the threshold. In this case, I fill the area below the line, like so:
However, in cases where values violate the threshold when they are below it, I want to fill the area above the line. Because I don't know how, the below image looks a bit weird. It'd be better if only the big dip at the beginning was in red. Like the reverse effect of the first image.
How can I fill the area above a line chart in AmCharts 3?
My current configuration (excuse the PHP, my frontend app eats JSON):
array(
'id' => 'major',
'valueAxis' => 'result',
'valueField' => 'result',
'type' => 'smoothedLine',
'lineThickness' => 2,
'lineAlpha' => 1,
'lineColor' => $threshold_at_top ? 'gold' : 'crimson',
'fillAlphas' => $threshold_at_top ? 0.001 : 0.1,
'negativeLineAlpha' => 1,
'negativeLineColor' => $threshold_at_top ? 'crimson' : 'gold',
'negativeFillAlphas' => $threshold_at_top ? 0.1 : 0.001,
'negativeBase' => $threshold_major,
'bullet' => 'none',
'balloon' => array(
'enabled' => false
)
),
array(
'id' => 'minor',
'valueAxis' => 'result',
'valueField' => 'result',
'type' => 'smoothedLine',
'lineThickness' => 2,
'lineAlpha' => $threshold_at_top ? 1 : 0,
'lineColor' => $threshold_at_top ? 'teal' : 'crimson',
'fillAlphas' => $threshold_at_top ? 0.001 : 0.1,
'negativeLineAlpha' => $threshold_at_top ? 0 : 1,
'negativeLineColor' => $threshold_at_top ? 'crimson' : 'teal',
'negativeFillAlphas' => $threshold_at_top ? 0.1 : 0.001,
'negativeBase' => $threshold_minor,
'bullet' => 'none',
'balloonText' => '<b>Result</b><br /><span style="font-size:1.5em;">[[value]]' . ( $last_datapoint->is_percentage ? ' %' : '' ) . '</span>',
'balloon' => array(
'adjustBorderColor' => false,
'color' => '#f1f1f1',
'fillColor' => '#2d87c3'
)
)
minor is the same line chart drawn on top of major.
What I've tried so far
When $threshold_at_top == true, I add another (invisible) top graph, which is simply the same value at each datapoint. This value is above all other values of the other graphs. For example, when I'm plotting a graph with results between 0 and 100, I plot this hidden top graph at 100.
Then I add it to the graphs object (as first element):
array_unshift( $options[ 'graphs' ], array(
'id' => 'top',
'valueAxis' => 'result',
'valueField' => 'top',
'type' => 'smoothedLine',
'lineAlpha' => 0,
'fillAlphas' => 0,
'bullet' => 'none',
'balloon' => array(
'enabled' => false
)
));
Then, I tell my existing major and minor graphs to 'fillToGraph' : 'top':
$options[ 'graphs' ][ 3 ][ 'fillToGraph' ] = 'top';
$options[ 'graphs' ][ 4 ][ 'fillToGraph' ] = 'top';
This gives the desired effect, but only when zoomed in enough:
When scrolling the same chart further to the right, new datapoints come into view, and it somehow messes up the area filled:
I reached out to AmCharts support, and they confirmed my suspicion (emphasis mine):
I checked with colleagues and I just wanted to let you know that
regular line graphs can support both fillToGraph and negativeFill at
the same time. You can see this behavior in the example below:
https://codepen.io/team/amcharts/pen/f8d6c8c5d3a2b4550a2b99f7486355e5?editors=0010
"graphs": [{
"id": "fromGraph",
"fillAlphas": 0.2,
"fillToGraph": "toGraph",
//"type": "smoothedLine",
"lineAlpha": 1,
"showBalloon": false,
"valueField": "fromValue",
"negativeBase": 40,
"negativeLineColor": "crimson"
}...
Therefore, we suggest using regular lines instead of smoothedLines, if
at all possible.
It's not possible to create my desired effect using smoothedLine graphs. See the bug below:

Plone Translations - i18ndude Preferred Language

I am hoping this is something simple I am just overlooking. We have 3 Plone sites that are supposed to be exactly the same in their core setup, only differing with certain products installed and the actual content. I noticed our translations are working on one site, and not on the other two. So far I can't find any differences.
We are using i18ndude (version 3.3.3) with Plone 4.3.2. We do have custom products/types with our own domain, but it is more than just those not working, it is everything in the site.
For testing, I have tried just grabbing and printing the browser's language. I did it with both context.REQUEST['LANGUAGE'] and context.portal_languages.getPreferredLanguage(). I set my browser language in each attempt to 'es', 'en', and 'pt', as those are the languages we are currently supporting. The Site Language in each site is set to English. Here are my test results:
Browser Language set to 'es':
Site A: returned 'es'
Site B: returned 'en'
Site C: returned 'en'
Browser Language set to 'en':
Site A: returned 'en'
Site B: returned 'en'
Site C: returned 'en'
Browser Language set to 'pt':
Site A: returned 'en'
Site B: returned 'en'
Site C: returned 'en'
Site A and B are both on the same server, so I don't believe its a missing server package. The buildouts are almost identical for those two, but the differences are just in a couple eggs that are seemingly unrelated to this issue.
I just don't understand why it isn't even detecting the updated browser language at all, it just defaults back to the site's preferred language it seems. Except for one scenario in one site. What is strange is, these all used to work to the best of my knowledge, and I am not sure when they stopped.
I did check context.portal_languages.getAvailableLanguages() just to make sure the ones I am using are in there, and they are. I also checked the ownership and permissions of the locales & i18n directories, those are all a match across sites and set accurately.
EDIT
This is a script I quickly wrote to see what all values Plone is getting:
pl = context.portal_languages
langs = [str(language) for language in pl.getAvailableLanguages().keys()]
print langs
print "Preferred: ", pl.getPreferredLanguage()
ts = context.translation_service
print "Request Language: ", context.REQUEST['LANGUAGE']
print "Accept Language: ", context.REQUEST['HTTP_ACCEPT_LANGUAGE']
return printed
This is my browser language setup when running this, listed by highest priority first:
pt-br
pt
es
en
en-us
And this is my result (site A, which seems to recognize Spanish, but not Portuguese):
['gv', 'gu', 'gd', 'ga', 'gn', 'gl', 'lg', 'lb', 'ty', 'ln', 'tw', 'tt', 'tr', 'ts', 'li', 'tn', 'to', 'tl', 'lu', 'tk', 'th', 'ti', 'tg', 'as', 'te', 'ta', 'yi', 'yo', 'de', 'ko', 'da', 'dz', 'dv', 'qu', 'kn', 'lv', 'el', 'eo', 'en', 'zh', 'ee', 'za', 'uk', 'eu', 'zu', 'es', 'ru', 'rw', 'kl', 'rm', 'rn', 'ro', 'bn', 'be', 'bg', 'ba', 'wa', 'wo', 'bm', 'jv', 'bo', 'bh', 'bi', 'br', 'bs', 'ja', 'om', 'oj', 'la', 'oc', 'kj', 'lo', 'os', 'or', 'xh', 'ch', 'co', 'ca', 'ce', 'cy', 'cs', 'cr', 'cv', 'cu', 'ps', 'pt', 'lt', 'pa', 'pi', 'ak', 'pl', 'hz', 'hy', 'an', 'hr', 'am', 'ht', 'hu', 'hi', 'ho', 'ha', 'he', 'mg', 'uz', 'ml', 'mo', 'mn', 'mi', 'mh', 'mk', 'ur', 'mt', 'ms', 'mr', 'ug', 'my', 'ki', 'aa', 'ab', 'ae', 've', 'af', 'vi', 'is', 'vk', 'iu', 'it', 'vo', 'ii', 'ay', 'ik', 'ar', 'km', 'io', 'et', 'ia', 'az', 'ie', 'id', 'ig', 'ks', 'nl', 'nn', 'no', 'na', 'nb', 'nd', 'ne', 'ng', 'ny', 'kw', 'nr', 'nv', 'kv', 'fr', 'ku', 'fy', 'fa', 'kk', 'ff', 'fi', 'fj', 'ky', 'fo', 'ka', 'kg', 'ss', 'sr', 'sq', 'sw', 'sv', 'su', 'st', 'sk', 'kr', 'si', 'sh', 'so', 'sn', 'sm', 'sl', 'sc', 'sa', 'sg', 'se', 'sd']
Preferred: es
Request Language: es
Accept Language: pt-br,pt;q=0.8,es;q=0.6,en;q=0.4,en-us;q=0.2
And results for Site B and C:
['en-mp', 'gv', 'gu', 'fr-dj', 'fr-gb', 'en-na', 'en-ng', 'en-nf', 'zh-hk', 'gd', 'pt-br', 'ga', 'gn', 'gl', 'en-nu', 'en-fm', 'en-ag', 'ms-my', 'ty', 'tw', 'tt', 'tr', 'ts', 'ko-kp', 'tn', 'to', 'tl', 'tk', 'th', 'ti', 'tg', 'te', 'zh-sg', 'ta', 'fr-mq', 'de', 'da', 'ar-ae', 'es-ni', 'dz', 'en-kn', 'fr-ml', 'dv', 'en-ms', 'fr-mg', 'fr-sc', 'fr-vu', 'qu', 'ar-qa', 'es-bo', 'en-nz', 'fr-bj', 'en-ws', 'fr-bi', 'zh', 'en-lr', 'fr-ch', 'fr-bf', 'za', 'fr-be', 'en-lc', 'fr-rw', 'zu', 'ch-mp', 'ar-ly', 'en-gb', 'en-nr', 'es-pr', 'tr-bg', 'en-gh', 'en-gi', 'fr-km', 'es-py', 'en-gm', 'es-pe', 'es-pa', 'en-gu', 'en-gy', 'sw-tz', 'ms-sg', 'wa', 'pt-st', 'wo', 'pt-ao', 'jv', 'fr-cd', 'ja', 'en-vu', 'es-ar', 'fr-td', 'fr-tg', 'da-dk', 'ch', 'co', 'en-vg', 'en-bz', 'ca', 'en-us', 'ce', 'en-ai', 'en-bm', 'en-vi', 'cy', 'en-bn', 'cs', 'cr', 'fr-ci', 'cv', 'cu', 'en-bb', 'ps', 'ln-cg', 'pt', 'en-au', 'zh-tw', 'es-mx', 'de-de', 'pa', 'es-ve', 'en-as', 'en-er', 'pi', 'de-dk', 'pl', 'en-sb', 'ch-gu', 'es-hn', 'en-sc', 'fr-nc', 'it-hr', 'ar-eg', 'mg', 'pt-pt', 'ml', 'mo', 'mn', 'mi', 'mh', 'mk', 'mt', 'ms', 'mr', 'fr-fr', 'hu-si', 'my', 'sv-fi', 'fr-re', 'en-pk', 've', 'vi', 'is', 'vk', 'iu', 'it', 'vo', 'ii', 'ik', 'en-io', 'fr-cm', 'io', 'ia', 'ie', 'id', 'ig', 'es-cu', 'hu-hu', 'es-cr', 'es-cl', 'es-co', 'fr-wf', 'pt-mz', 'en-il', 'it-it', 'de-be', 'fr', 'en-ke', 'fr-ga', 'fr-pf', 'es-do', 'ar-ps', 'fy', 'fr-gn', 'fr-pm', 'en-ki', 'en-ug', 'fa', 'fr-gp', 'ff', 'fi', 'fj', 'fo', 'ar-kw', 'bn-sg', 'ss', 'sr', 'sq', 'sw', 'sv', 'su', 'st', 'sk', 'si', 'sh', 'so', 'sn', 'sm', 'sl', 'sc', 'sa', 'sg', 'se', 'sd', 'bn-in', 'fr-mc', 'sv-se', 'ar-bh', 'lg', 'lb', 'la', 'ln', 'lo', 'ss-za', 'li', 'lv', 'lt', 'lu', 'sw-ke', 'en-bw', 'yi', 'en-ph', 'en-pn', 'yo', 'en-ie', 'en-pg', 'pt-cv', 'hr-ba', 'bn-bd', 'en-pr', 'en-pw', 'ss-sz', 'ar-iq', 'de-ch', 'ar-il', 'es-sv', 'el', 'eo', 'en', 'ar-dz', 'ee', 'tn-bw', 'es-gq', 'fr-gf', 'es-gt', 'eu', 'et', 'de-lu', 'es', 'ru', 'rw', 'zh-cn', 'ar-td', 'nl-nl', 'it-sm', 'it-si', 'rm', 'rn', 'ro', 'ar-sa', 'be', 'bg', 'ur-pk', 'ba', 'fr-ca', 'bm', 'bn', 'bo', 'bh', 'bi', 'fr-cg', 'fr-cf', 'es-us', 'el-cy', 'en-vc', 'sd-pk', 'ta-sg', 'br', 'bs', 'nl-an', 'sd-in', 'cs-cz', 'om', 'oj', 'fr-lb', 'en-fk', 'en-fj', 'oc', 'ln-cd', 'fr-lu', 'ar-om', 'de-at', 'os', 'or', 'tr-cy', 'xh', 'el-gr', 'de-li', 'ar-sy', 'en-jm', 'es-ec', 'ar-so', 'it-ch', 'en-ls', 'ar-sd', 'es-es', 'en-rw', 'tn-za', 'ar-jo', 'en-ky', 'en-bs', 'hz', 'ar-ma', 'da-gl', 'hy', 'en-mt', 'en-mu', 'nl-aw', 'en-mw', 'hr', 'en-tt', 'en-zw', 'ht', 'hu', 'en-to', 'ar-mr', 'hi', 'en-tk', 'ho', 'hr-hr', 'ha', 'en-tc', 'pt-gw', 'he', 'en-dm', 'fr-it', 'uz', 'en-et', 'ur-in', 'ur', 'tr-tr', 'uk', 'ms-bn', 'ug', 'aa', 'en-so', 'en-sl', 'ab', 'ae', 'en-sh', 'af', 'en-sg', 'ak', 'am', 'ko-kr', 'an', 'as', 'ar', 'en-sz', 'nl-be', 'ay', 'az', 'ar-lb', 'nl', 'nn', 'no', 'na', 'nb', 'nd', 'ne', 'ng', 'ny', 'ta-in', 'fr-yt', 'en-za', 'nr', 'nv', 'ar-ye', 'ar-tn', 'en-cm', 'en-ck', 'sr-ba', 'en-ca', 'ka', 'kg', 'en-gd', 'es-uy', 'kk', 'kj', 'ki', 'ko', 'kn', 'km', 'kl', 'ks', 'kr', 'fr-ad', 'kw', 'kv', 'ku', 'en-zm', 'ky', 'fr-ht', 'nl-sr']
Preferred: en
Request Language: en
Accept Language: pt-br,pt;q=0.8,es;q=0.6,en;q=0.4,en-us;q=0.2
I just noticed that the list of available languages from portal_languages is different between those sites. Adding to the strange, but maybe a hint to the culprit?
Sorry for the long post, just trying to give as much info as I can!
My suspicions were right about it being something simple I am overlooking. Posting my find here.
In the ZMI, go to portal_languages and check these settings:
Default Language
Allowed Languages
ALL supported languages should be selected.
Negotiation Scheme
Make sure "Use browser language request negotiation" is checked
My issue was that only the Default language was selected in the Allowed Languages selection list. I am not sure why it go reset like this or how. When using the Language Settings Control Panel I did not see the Allowed Languages option, had to go to ZMI for it.
Apparently the changes mentioned by hvelarde did not update this setting either.
Search the instance part of your buildout for the environment variable zope_i18n_allowed_languages; it is used to restrict the languages for which po files are loaded to speed up Zope startup time and use less memory.
In your case, you should set it as follows:
[instance]
...
environment-vars =
PTS_LANGUAGES en es pt
zope_i18n_allowed_languages en es pt
zope_i18n_compile_mo_files true
For more information check Maurits van Rees' Internationalization in Plone 3.3 and 4.0.

Resources