1. #!/usr/bin/python
  2.  
  3. fail = "?" # need a marker for fail
  4.  
  5. #############################################
  6. # how to define one variable
  7.  
  8. def var(x):
  9. "Match needs variables to mark what can be matched."
  10. return isinstance(x,str) and x and x[0] == "?"
  11.  
  12. def _var():
  13. """
  14. should print
  15. True
  16. False
  17. """
  18. print(var("?gg"))
  19. print(var(22))
  20.  
  21. _var()
  22.  
  23. #############################################
  24. # how to define a list of bindongs
  25.  
  26. def assoc(x,pairs):
  27. "Finding one item in a list of pairs."
  28. for a,b in pairs:
  29. if a==x:
  30. return b
  31. return fail
  32.  
  33. def assocp(x,pairs):
  34. "True if the pairs contains an association"
  35. return not assoc(x,pairs) == fail
  36.  
  37. def binding(x,pairs) :
  38. "Recursive chase of associations."
  39. y = assoc(x,pairs)
  40. if y == fail:
  41. return fail
  42. else:
  43. if var(y):
  44. return binding(y,pairs)
  45. else:
  46. return y
  47. def _binding():
  48. """
  49. should print
  50. ?x 10
  51. ?y 100
  52. ?z 100
  53. ?w ?
  54. 10 ?
  55. """
  56. mypairs= [("?x",10),
  57. ("?y","?z"),
  58. ("?z",100)]
  59. for goal in ["?x","?y","?z","?w",10]:
  60. print goal, binding(goal,mypairs)
  61.  
  62. _binding()
  63.  
  64. ###################################################
  65. # matching
  66.  
  67. """
  68. 1. If x and y are eql they match; otherwise,
  69.  
  70. 2. If x is a variable that has a binding,
  71. they match if it matches y;otherwise,
  72. - note that this recursive call would look like this:
  73. match(binding(x,pairs),y,pairs)
  74.  
  75. 3. If y is a variable that has a binding,
  76. they match if it matches x;otherwise,
  77.  
  78. 4. If x is a variable (without a binding),
  79. they match and thereby establish a binding for it; otherwise,
  80.  
  81. 5. If y is a variable (without a binding),
  82. they match and thereby establish a binding for it; otherwise,
  83.  
  84. 6. They match if they are both tuples, and the heads match,
  85. and the rest match with the bindings generated thereby.
  86. """
  87.  
  88.  
  89. def _match():
  90. # returns true
  91. print 0,match("p","p")
  92. #returns true
  93. print 1,match(("a","b","c"),
  94. ("a","b","c"))
  95. # returns true and updates the ?x binding
  96. print 2,match(("a","b","?x"),
  97. ("a","b","c"))
  98. # returns true and updates the ?x binding
  99. print 3,match(("a","b", "c"),
  100. ("a","b","?x"))
  101. # fails
  102. print 4,match(("a","b","c"),
  103. ("a","b","d"))
  104. # returns true and updates the ?x and ?y binding
  105. print 5,match(("p","a" , "b","c","a"),
  106. ("p","?x","?y","c","?x"))
  107. # returns fail since we try to bind ?x to two things
  108. print 6,match(("p","a" , "b","c","d"),
  109. ("p","?x","?y","c","?x"))
  110. # returns true and updates the ?x and ?y binding and ?y binds to ?x
  111. print 7,match(("p","?x","b","?y","a"),
  112. ("p","?y","b","c" ,"a"))
  113. # returns true and no env updates
  114. print 8,match(("p", "?x"),
  115. ("p", "?x"))
  116. # say what?
  117. print 9,match(("p","?v" ,"b" ,"d",("?z", "?z")),
  118. ("p","a","?w","c","?y", ("e", "e")),
  119. [("?z","e"),
  120. ("?y","d"),
  121. ("?x","c"),
  122. ("?v","a"),
  123. ("?w","b")])