         
         return "Constraint<(\(expression)) | strength: \(Strength.readableString(strength)) | operator: \(op)>"
     }
-
-    private var _expression: Expression
     
     /// The expression held by the constraint
-    public var expression: Expression {
-        get { return _expression }
-        set { _expression = newValue }
-    }
+    private(set) var expression: Expression
 
-    private var _strength: Double
-    
     /// The strength of the constraint
-    public var strength: Double {
-        get { return _strength }
-        set { _strength = newValue }
-    }
+    public var strength: Double
 
-    private var _op: RelationalOperator
-    
     /// The operator of the constraint
-    public var op: RelationalOperator {
-        get { return _op }
-        set { _op = newValue }
-    }
+    private(set) var op: RelationalOperator
     
     /// Create a constraint with the given expression and operator
     public convenience init(expr: Expression, op: RelationalOperator) {

    
    /// Set the strength of the constraint
    public func setStrength(_ newStrength: Double) -> Constraint {
        _strength = newStrength
        return self
    }


    
    /// Create a constraint with the given expression, operator and strength
    public init(expr: Expression, op: RelationalOperator, strength: Double) {
        self.expression = Constraint.reduce(expr)
        self.op = op
        self.strength = Strength.clip(strength)
    }
    
    /// Create a constraint, copying the provided constraint, with the given strength
